diff --git a/.azure-pipelines/templates/changelog.yml b/.azure-pipelines/templates/changelog.yml index 7619858a9..4a65e2c2b 100644 --- a/.azure-pipelines/templates/changelog.yml +++ b/.azure-pipelines/templates/changelog.yml @@ -4,7 +4,7 @@ jobs: vmImage: vs2017-win2016 steps: - bash: | - CERTBOT_VERSION="$(python -c "import certbot; print(certbot.__version__)")" + CERTBOT_VERSION="$(cd certbot && python -c "import certbot; print(certbot.__version__)" && cd ~-)" "${BUILD_REPOSITORY_LOCALPATH}\tools\extract_changelog.py" "${CERTBOT_VERSION}" >> "${BUILD_ARTIFACTSTAGINGDIRECTORY}/release_notes.md" displayName: Prepare changelog - task: PublishPipelineArtifact@1 diff --git a/.azure-pipelines/templates/installer-tests.yml b/.azure-pipelines/templates/installer-tests.yml index b1c5ea6b1..e3a005334 100644 --- a/.azure-pipelines/templates/installer-tests.yml +++ b/.azure-pipelines/templates/installer-tests.yml @@ -1,5 +1,5 @@ jobs: - - job: installer + - job: installer_build pool: vmImage: vs2017-win2016 steps: @@ -20,10 +20,32 @@ jobs: path: $(Build.ArtifactStagingDirectory) artifact: windows-installer displayName: Publish Windows installer - - script: $(Build.ArtifactStagingDirectory)\certbot-beta-installer-win32.exe /S + - job: installer_run + dependsOn: installer_build + strategy: + matrix: + win2019: + imageName: windows-2019 + win2016: + imageName: vs2017-win2016 + win2012r2: + imageName: vs2015-win2012r2 + pool: + vmImage: $(imageName) + steps: + - 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: | - python -m venv venv + py -3 -m venv venv venv\Scripts\python tools\pip_install.py -e certbot-ci displayName: Prepare Certbot-CI - script: | diff --git a/.gitignore b/.gitignore index 68762da6b..6dd422187 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ tags \#*# .idea .ropeproject +.vscode # auth --cert-path --chain-path /*.pem diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 000000000..11c895f4d --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,7 @@ +[settings] +skip_glob=venv* +skip=letsencrypt-auto-source +force_sort_within_sections=True +force_single_line=True +order_by_type=False +line_length=400 diff --git a/.pylintrc b/.pylintrc index bd4eab11a..0e78828bd 100644 --- a/.pylintrc +++ b/.pylintrc @@ -24,6 +24,11 @@ persistent=yes # usually to register additional checkers. load-plugins=linter_plugin +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-whitelist=pywintypes,win32api,win32file,win32security + [MESSAGES CONTROL] @@ -41,10 +46,14 @@ load-plugins=linter_plugin # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" -disable=fixme,locally-disabled,locally-enabled,abstract-class-not-used,abstract-class-little-used,bad-continuation,too-few-public-methods,no-self-use,invalid-name,too-many-instance-attributes,cyclic-import,duplicate-code -# abstract-class-not-used cannot be disabled locally (at least in -# pylint 1.4.1), same for abstract-class-little-used - +# CERTBOT COMMENT +# 1) Once certbot codebase is claimed to be compatible exclusively with Python 3, +# the useless-object-inheritance check can be enabled again, and code fixed accordingly. +# 2) Check unsubscriptable-object tends to create a lot of false positives. Let's disable it. +# See https://github.com/PyCQA/pylint/issues/1498. +# 3) Same as point 2 for no-value-for-parameter. +# See https://github.com/PyCQA/pylint/issues/2820. +disable=fixme,locally-disabled,locally-enabled,bad-continuation,no-self-use,invalid-name,cyclic-import,duplicate-code,design,import-outside-toplevel,useless-object-inheritance,unsubscriptable-object,no-value-for-parameter,no-else-return,no-else-raise,no-else-break,no-else-continue [REPORTS] @@ -297,40 +306,6 @@ valid-classmethod-first-arg=cls valid-metaclass-classmethod-first-arg=mcs -[DESIGN] - -# Maximum number of arguments for function / method -max-args=6 - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=(unused)?_.*|dummy - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=12 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - - [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to diff --git a/.travis.yml b/.travis.yml index 22391c84f..fdb692ac1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,12 +46,9 @@ matrix: - python: "2.7" env: TOXENV=py27-cover FYI="py27 tests + code coverage" - - python: "2.7" + - python: "3.7" env: TOXENV=lint <<: *not-on-master - - python: "3.4" - env: TOXENV=mypy - <<: *not-on-master - python: "3.5" env: TOXENV=mypy <<: *not-on-master @@ -178,7 +175,7 @@ matrix: - python: "3.7" env: TOXENV=py37 <<: *extended-test-suite - - python: "3.8-dev" + - python: "3.8" env: TOXENV=py38 <<: *extended-test-suite - python: "3.4" @@ -221,10 +218,10 @@ matrix: sudo: required services: docker <<: *extended-test-suite - - python: "3.8-dev" + - python: "3.8" env: ACME_SERVER=boulder-v1 TOXENV=integration <<: *extended-test-suite - - python: "3.8-dev" + - python: "3.8" env: ACME_SERVER=boulder-v2 TOXENV=integration <<: *extended-test-suite - sudo: required @@ -235,6 +232,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 diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 7806b2ffe..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,1844 +0,0 @@ -# Certbot change log - -Certbot adheres to [Semantic Versioning](https://semver.org/). - -## 1.0.0 - master - -### Added - -* - -### Changed - -* Certbot's `config_changes` subcommand has been removed -* `certbot.plugins.common.TLSSNI01` has been removed. -* Deprecated attributes related to the TLS-SNI-01 challenge in - `acme.challenges` and `acme.standalone` - have been removed. -* The functions `certbot.client.view_config_changes`, - `certbot.main.config_changes`, - `certbot.plugins.common.Installer.view_config_changes`, - `certbot.reverter.Reverter.view_config_changes`, and - `certbot.util.get_systemd_os_info` have been removed - -### Fixed - -* - -More details about these changes can be found on our GitHub repo. - -## 0.40.1 - 2019-11-05 - -### Changed - -* Added back support for Python 3.4 to Certbot components and certbot-auto due - to a bug when requiring Python 2.7 or 3.5+ on RHEL 6 based systems. - -More details about these changes can be found on our GitHub repo. - -## 0.40.0 - 2019-11-05 - -### Added - -* - -### Changed - -* We deprecated support for Python 3.4 in Certbot and its ACME library. Support - for Python 3.4 will be removed in the next major release of Certbot. - certbot-auto users on RHEL 6 based systems will be asked to enable Software - Collections (SCL) repository so Python 3.6 can be installed. certbot-auto can - enable the SCL repo for you on CentOS 6 while users on other RHEL 6 based - systems will be asked to do this manually. -* `--server` may now be combined with `--dry-run`. Certbot will, as before, use the - staging server instead of the live server when `--dry-run` is used. -* `--dry-run` now requests fresh authorizations every time, fixing the issue - where it was prone to falsely reporting success. -* Updated certbot-dns-google to depend on newer versions of - google-api-python-client and oauth2client. -* The OS detection logic again uses distro library for Linux OSes -* certbot.plugins.common.TLSSNI01 has been deprecated and will be removed in a - future release. -* CLI flags --tls-sni-01-port and --tls-sni-01-address have been removed. -* The values tls-sni and tls-sni-01 for the --preferred-challenges flag are no - longer accepted. -* Removed the flags: `--agree-dev-preview`, `--dialog`, and `--apache-init-script` -* acme.standalone.BaseRequestHandlerWithLogging and - acme.standalone.simple_tls_sni_01_server have been deprecated and will be - removed in a future release of the library. -* certbot-dns-rfc2136 now use TCP to query SOA records. - -### Fixed - -* - -More details about these changes can be found on our GitHub repo. - -## 0.39.0 - 2019-10-01 - -### Added - -* Support for Python 3.8 was added to Certbot and all of its components. -* Support for CentOS 8 was added to certbot-auto. - -### Changed - -* Don't send OCSP requests for expired certificates -* Return to using platform.linux_distribution instead of distro.linux_distribution in OS fingerprinting for Python < 3.8 -* Updated the Nginx plugin's TLS configuration to keep support for some versions of IE11. - -### Fixed - -* Fixed OS detection in the Apache plugin on RHEL 6. - -More details about these changes can be found on our GitHub repo. - -## 0.38.0 - 2019-09-03 - -### Added - -* Disable session tickets for Nginx users when appropriate. - -### Changed - -* If Certbot fails to rollback your server configuration, the error message - links to the Let's Encrypt forum. Change the link to the Help category now - that the Server category has been closed. -* Replace platform.linux_distribution with distro.linux_distribution as a step - towards Python 3.8 support in Certbot. - -### Fixed - -* Fixed OS detection in the Apache plugin on Scientific Linux. - -More details about these changes can be found on our GitHub repo. - -## 0.37.2 - 2019-08-21 - -* Stop disabling TLS session tickets in Nginx as it caused TLS failures on - some systems. - -More details about these changes can be found on our GitHub repo. - -## 0.37.1 - 2019-08-08 - -### Fixed - -* Stop disabling TLS session tickets in Apache as it caused TLS failures on - some systems. - -More details about these changes can be found on our GitHub repo. - -## 0.37.0 - 2019-08-07 - -### Added - -* Turn off session tickets for apache plugin by default -* acme: Authz deactivation added to `acme` module. - -### Changed - -* Follow updated Mozilla recommendations for Nginx ssl_protocols, ssl_ciphers, - and ssl_prefer_server_ciphers - -### Fixed - -* Fix certbot-auto failures on RHEL 8. - -More details about these changes can be found on our GitHub repo. - -## 0.36.0 - 2019-07-11 - -### Added - -* Turn off session tickets for nginx plugin by default -* Added missing error types from RFC8555 to acme - -### Changed - -* Support for Ubuntu 14.04 Trusty has been removed. -* Update the 'manage your account' help to be more generic. -* The error message when Certbot's Apache plugin is unable to modify your - Apache configuration has been improved. -* Certbot's config_changes subcommand has been deprecated and will be - removed in a future release. -* `certbot config_changes` no longer accepts a --num parameter. -* The functions `certbot.plugins.common.Installer.view_config_changes` and - `certbot.reverter.Reverter.view_config_changes` have been deprecated and will - be removed in a future release. - -### Fixed - -* Replace some unnecessary platform-specific line separation. - -More details about these changes can be found on our GitHub repo. - -## 0.35.1 - 2019-06-10 - -### Fixed - -* Support for specifying an authoritative base domain in our dns-rfc2136 plugin - has been removed. This feature was added in our last release but had a bug - which caused the plugin to fail so the feature has been removed until it can - be added properly. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* certbot-dns-rfc2136 - -More details about these changes can be found on our GitHub repo. - -## 0.35.0 - 2019-06-05 - -### Added - -* dns_rfc2136 plugin now supports explicitly specifing an authorative - base domain for cases when the automatic method does not work (e.g. - Split horizon DNS) - -### Changed - -* - -### Fixed - -* Renewal parameter `webroot_path` is always saved, avoiding some regressions - when `webroot` authenticator plugin is invoked with no challenge to perform. -* Certbot now accepts OCSP responses when an explicit authorized - responder, different from the issuer, is used to sign OCSP - responses. -* Scripts in Certbot hook directories are no longer executed when their - filenames end in a tilde. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* certbot -* certbot-dns-rfc2136 - -More details about these changes can be found on our GitHub repo. - -## 0.34.2 - 2019-05-07 - -### Fixed - -* certbot-auto no longer writes a check_permissions.py script at the root - of the filesystem. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -changes in this release were to certbot-auto. - -More details about these changes can be found on our GitHub repo. - -## 0.34.1 - 2019-05-06 - -### Fixed - -* certbot-auto no longer prints a blank line when there are no permissions - problems. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -changes in this release were to certbot-auto. - -More details about these changes can be found on our GitHub repo. - -## 0.34.0 - 2019-05-01 - -### Changed - -* Apache plugin now tries to restart httpd on Fedora using systemctl if a - configuration test error is detected. This has to be done due to the way - Fedora now generates the self signed certificate files upon first - restart. -* Updated Certbot and its plugins to improve the handling of file system permissions - on Windows as a step towards adding proper Windows support to Certbot. -* Updated urllib3 to 1.24.2 in certbot-auto. -* Removed the fallback introduced with 0.32.0 in `acme` to retry a challenge response - with a `keyAuthorization` if sending the response without this field caused a - `malformed` error to be received from the ACME server. -* Linode DNS plugin now supports api keys created from their new panel - at [cloud.linode.com](https://cloud.linode.com) - -### Fixed - -* Fixed Google DNS Challenge issues when private zones exist -* Adding a warning noting that future versions of Certbot will automatically configure the - webserver so that all requests redirect to secure HTTPS access. You can control this - behavior and disable this warning with the --redirect and --no-redirect flags. -* certbot-auto now prints warnings when run as root with insecure file system - permissions. If you see these messages, you should fix the problem by - following the instructions at - https://community.letsencrypt.org/t/certbot-auto-deployment-best-practices/91979/, - however, these warnings can be disabled as necessary with the flag - --no-permissions-check. -* `acme` module uses now a POST-as-GET request to retrieve the registration - from an ACME v2 server -* Convert the tsig algorithm specified in the certbot_dns_rfc2136 configuration file to - all uppercase letters before validating. This makes the value in the config case - insensitive. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* acme -* certbot -* certbot-apache -* certbot-dns-cloudflare -* certbot-dns-cloudxns -* certbot-dns-digitalocean -* certbot-dns-dnsimple -* certbot-dns-dnsmadeeasy -* certbot-dns-gehirn -* certbot-dns-google -* certbot-dns-linode -* certbot-dns-luadns -* certbot-dns-nsone -* certbot-dns-ovh -* certbot-dns-rfc2136 -* certbot-dns-route53 -* certbot-dns-sakuracloud -* certbot-nginx - -More details about these changes can be found on our GitHub repo. - -## 0.33.1 - 2019-04-04 - -### Fixed - -* A bug causing certbot-auto to print warnings or crash on some RHEL based - systems has been resolved. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -changes in this release were to certbot-auto. - -More details about these changes can be found on our GitHub repo. - -## 0.33.0 - 2019-04-03 - -### Added - -* Fedora 29+ is now supported by certbot-auto. Since Python 2.x is on a deprecation - path in Fedora, certbot-auto will install and use Python 3.x on Fedora 29+. -* CLI flag `--https-port` has been added for Nginx plugin exclusively, and replaces - `--tls-sni-01-port`. It defines the HTTPS port the Nginx plugin will use while - setting up a new SSL vhost. By default the HTTPS port is 443. - -### Changed - -* Support for TLS-SNI-01 has been removed from all official Certbot plugins. -* Attributes related to the TLS-SNI-01 challenge in `acme.challenges` and `acme.standalone` - modules are deprecated and will be removed soon. -* CLI flags `--tls-sni-01-port` and `--tls-sni-01-address` are now no-op, will - generate a deprecation warning if used, and will be removed soon. -* Options `tls-sni` and `tls-sni-01` in `--preferred-challenges` flag are now no-op, - will generate a deprecation warning if used, and will be removed soon. -* CLI flag `--standalone-supported-challenges` has been removed. - -### Fixed - -* Certbot uses the Python library cryptography for OCSP when cryptography>=2.5 - is installed. We fixed a bug in Certbot causing it to interpret timestamps in - the OCSP response as being in the local timezone rather than UTC. -* Issue causing the default CentOS 6 TLS configuration to ignore some of the - HTTPS VirtualHosts created by Certbot. mod_ssl loading is now moved to main - http.conf for this environment where possible. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* acme -* certbot -* certbot-apache -* certbot-nginx - -More details about these changes can be found on our GitHub repo. - -## 0.32.0 - 2019-03-06 - -### Added - -* If possible, Certbot uses built-in support for OCSP from recent cryptography - versions instead of the OpenSSL binary: as a consequence Certbot does not need - the OpenSSL binary to be installed anymore if cryptography>=2.5 is installed. - -### Changed - -* Certbot and its acme module now depend on josepy>=1.1.0 to avoid printing the - warnings described at https://github.com/certbot/josepy/issues/13. -* Apache plugin now respects CERTBOT_DOCS environment variable when adding - command line defaults. -* The running of manual plugin hooks is now always included in Certbot's log - output. -* Tests execution for certbot, certbot-apache and certbot-nginx packages now relies on pytest. -* An ACME CA server may return a "Retry-After" HTTP header on authorization polling, as - specified in the ACME protocol, to indicate when the next polling should occur. Certbot now - reads this header if set and respect its value. -* The `acme` module avoids sending the `keyAuthorization` field in the JWS - payload when responding to a challenge as the field is not included in the - current ACME protocol. To ease the migration path for ACME CA servers, - Certbot and its `acme` module will first try the request without the - `keyAuthorization` field but will temporarily retry the request with the - field included if a `malformed` error is received. This fallback will be - removed in version 0.34.0. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* acme -* certbot -* certbot-apache -* certbot-nginx - -More details about these changes can be found on our GitHub repo. - -## 0.31.0 - 2019-02-07 - -### Added - -* Avoid reprocessing challenges that are already validated - when a certificate is issued. -* Support for initiating (but not solving end-to-end) TLS-ALPN-01 challenges - with the `acme` module. - -### Changed - -* Certbot's official Docker images are now based on Alpine Linux 3.9 rather - than 3.7. The new version comes with OpenSSL 1.1.1. -* Lexicon-based DNS plugins are now fully compatible with Lexicon 3.x (support - on 2.x branch is maintained). -* Apache plugin now attempts to configure all VirtualHosts matching requested - domain name instead of only a single one when answering the HTTP-01 challenge. - -### Fixed - -* Fixed accessing josepy contents through acme.jose when the full acme.jose - path is used. -* Clarify behavior for deleting certs as part of revocation. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* acme -* certbot -* certbot-apache -* certbot-dns-cloudxns -* certbot-dns-dnsimple -* certbot-dns-dnsmadeeasy -* certbot-dns-gehirn -* certbot-dns-linode -* certbot-dns-luadns -* certbot-dns-nsone -* certbot-dns-ovh -* certbot-dns-sakuracloud - -More details about these changes can be found on our GitHub repo. - -## 0.30.2 - 2019-01-25 - -### Fixed - -* Update the version of setuptools pinned in certbot-auto to 40.6.3 to - solve installation problems on newer OSes. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, this -release only affects certbot-auto. - -More details about these changes can be found on our GitHub repo. - -## 0.30.1 - 2019-01-24 - -### Fixed - -* Always download the pinned version of pip in pipstrap to address breakages -* Rename old,default.conf to old-and-default.conf to address commas in filenames - breaking recent versions of pip. -* Add VIRTUALENV_NO_DOWNLOAD=1 to all calls to virtualenv to address breakages - from venv downloading the latest pip - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* certbot-apache - -More details about these changes can be found on our GitHub repo. - -## 0.30.0 - 2019-01-02 - -### Added - -* Added the `update_account` subcommand for account management commands. - -### Changed - -* Copied account management functionality from the `register` subcommand - to the `update_account` subcommand. -* Marked usage `register --update-registration` for deprecation and - removal in a future release. - -### Fixed - -* Older modules in the josepy library can now be accessed through acme.jose - like it could in previous versions of acme. This is only done to preserve - backwards compatibility and support for doing this with new modules in josepy - will not be added. Users of the acme library should switch to using josepy - directly if they haven't done so already. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* acme - -More details about these changes can be found on our GitHub repo. - -## 0.29.1 - 2018-12-05 - -### Added - -* - -### Changed - -* - -### Fixed - -* The default work and log directories have been changed back to - /var/lib/letsencrypt and /var/log/letsencrypt respectively. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* certbot - -More details about these changes can be found on our GitHub repo. - -## 0.29.0 - 2018-12-05 - -### Added - -* Noninteractive renewals with `certbot renew` (those not started from a - terminal) now randomly sleep 1-480 seconds before beginning work in - order to spread out load spikes on the server side. -* Added External Account Binding support in cli and acme library. - Command line arguments --eab-kid and --eab-hmac-key added. - -### Changed - -* Private key permissioning changes: Renewal preserves existing group mode - & gid of previous private key material. Private keys for new - lineages (i.e. new certs, not renewed) default to 0o600. - -### Fixed - -* Update code and dependencies to clean up Resource and Deprecation Warnings. -* Only depend on imgconverter extension for Sphinx >= 1.6 - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* acme -* certbot -* certbot-apache -* certbot-dns-cloudflare -* certbot-dns-digitalocean -* certbot-dns-google -* certbot-nginx - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/62?closed=1 - -## 0.28.0 - 2018-11-7 - -### Added - -* `revoke` accepts `--cert-name`, and doesn't accept both `--cert-name` and `--cert-path`. -* Use the ACMEv2 newNonce endpoint when a new nonce is needed, and newNonce is available in the directory. - -### Changed - -* Removed documentation mentions of `#letsencrypt` IRC on Freenode. -* Write README to the base of (config-dir)/live directory -* `--manual` will explicitly warn users that earlier challenges should remain in place when setting up subsequent challenges. -* Warn when using deprecated acme.challenges.TLSSNI01 -* Log warning about TLS-SNI deprecation in Certbot -* Stop preferring TLS-SNI in the Apache, Nginx, and standalone plugins -* OVH DNS plugin now relies on Lexicon>=2.7.14 to support HTTP proxies -* Default time the Linode plugin waits for DNS changes to propogate is now 1200 seconds. - -### Fixed - -* Match Nginx parser update in allowing variable names to start with `${`. -* Fix ranking of vhosts in Nginx so that all port-matching vhosts come first -* Correct OVH integration tests on machines without internet access. -* Stop caching the results of ipv6_info in http01.py -* Test fix for Route53 plugin to prevent boto3 making outgoing connections. -* The grammar used by Augeas parser in Apache plugin was updated to fix various parsing errors. -* The CloudXNS, DNSimple, DNS Made Easy, Gehirn, Linode, LuaDNS, NS1, OVH, and - Sakura Cloud DNS plugins are now compatible with Lexicon 3.0+. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* acme -* certbot -* certbot-apache -* certbot-dns-cloudxns -* certbot-dns-dnsimple -* certbot-dns-dnsmadeeasy -* certbot-dns-gehirn -* certbot-dns-linode -* certbot-dns-luadns -* certbot-dns-nsone -* certbot-dns-ovh -* certbot-dns-route53 -* certbot-dns-sakuracloud -* certbot-nginx - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/59?closed=1 - -## 0.27.1 - 2018-09-06 - -### Fixed - -* Fixed parameter name in OpenSUSE overrides for default parameters in the - Apache plugin. Certbot on OpenSUSE works again. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* certbot-apache - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/60?closed=1 - -## 0.27.0 - 2018-09-05 - -### Added - -* The Apache plugin now accepts the parameter --apache-ctl which can be - used to configure the path to the Apache control script. - -### Changed - -* When using `acme.client.ClientV2` (or - `acme.client.BackwardsCompatibleClientV2` with an ACME server that supports a - newer version of the ACME protocol), an `acme.errors.ConflictError` will be - raised if you try to create an ACME account with a key that has already been - used. Previously, a JSON parsing error was raised in this scenario when using - the library with Let's Encrypt's ACMEv2 endpoint. - -### Fixed - -* When Apache is not installed, Certbot's Apache plugin no longer prints - messages about being unable to find apachectl to the terminal when the plugin - is not selected. -* If you're using the Apache plugin with the --apache-vhost-root flag set to a - directory containing a disabled virtual host for the domain you're requesting - a certificate for, the virtual host will now be temporarily enabled if - necessary to pass the HTTP challenge. -* The documentation for the Certbot package can now be built using Sphinx 1.6+. -* You can now call `query_registration` without having to first call - `new_account` on `acme.client.ClientV2` objects. -* The requirement of `setuptools>=1.0` has been removed from `certbot-dns-ovh`. -* Names in certbot-dns-sakuracloud's tests have been updated to refer to Sakura - Cloud rather than NS1 whose plugin certbot-dns-sakuracloud was based on. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -package with changes other than its version number was: - -* acme -* certbot -* certbot-apache -* certbot-dns-ovh -* certbot-dns-sakuracloud - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/57?closed=1 - -## 0.26.1 - 2018-07-17 - -### Fixed - -* Fix a bug that was triggered when users who had previously manually set `--server` to get ACMEv2 certs tried to renew ACMEv1 certs. - -Despite us having broken lockstep, we are continuing to release new versions of all Certbot components during releases for the time being, however, the only package with changes other than its version number was: - -* certbot - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/58?closed=1 - -## 0.26.0 - 2018-07-11 - -### Added - -* A new security enhancement which we're calling AutoHSTS has been added to - Certbot's Apache plugin. This enhancement configures your webserver to send a - HTTP Strict Transport Security header with a low max-age value that is slowly - increased over time. The max-age value is not increased to a large value - until you've successfully managed to renew your certificate. This enhancement - can be requested with the --auto-hsts flag. -* New official DNS plugins have been created for Gehirn Infrastracture Service, - Linode, OVH, and Sakura Cloud. These plugins can be found on our Docker Hub - page at https://hub.docker.com/u/certbot and on PyPI. -* The ability to reuse ACME accounts from Let's Encrypt's ACMEv1 endpoint on - Let's Encrypt's ACMEv2 endpoint has been added. -* Certbot and its components now support Python 3.7. -* Certbot's install subcommand now allows you to interactively choose which - certificate to install from the list of certificates managed by Certbot. -* Certbot now accepts the flag `--no-autorenew` which causes any obtained - certificates to not be automatically renewed when it approaches expiration. -* Support for parsing the TLS-ALPN-01 challenge has been added back to the acme - library. - -### Changed - -* Certbot's default ACME server has been changed to Let's Encrypt's ACMEv2 - endpoint. By default, this server will now be used for both new certificate - lineages and renewals. -* The Nginx plugin is no longer marked labeled as an "Alpha" version. -* The `prepare` method of Certbot's plugins is no longer called before running - "Updater" enhancements that are run on every invocation of `certbot renew`. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -packages with functional changes were: - -* acme -* certbot -* certbot-apache -* certbot-dns-gehirn -* certbot-dns-linode -* certbot-dns-ovh -* certbot-dns-sakuracloud -* certbot-nginx - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/55?closed=1 - -## 0.25.1 - 2018-06-13 - -### Fixed - -* TLS-ALPN-01 support has been removed from our acme library. Using our current - dependencies, we are unable to provide a correct implementation of this - challenge so we decided to remove it from the library until we can provide - proper support. -* Issues causing test failures when running the tests in the acme package with - pytest<3.0 has been resolved. -* certbot-nginx now correctly depends on acme>=0.25.0. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -packages with changes other than their version number were: - -* acme -* certbot-nginx - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/56?closed=1 - -## 0.25.0 - 2018-06-06 - -### Added - -* Support for the ready status type was added to acme. Without this change, - Certbot and acme users will begin encountering errors when using Let's - Encrypt's ACMEv2 API starting on June 19th for the staging environment and - July 5th for production. See - https://community.letsencrypt.org/t/acmev2-order-ready-status/62866 for more - information. -* Certbot now accepts the flag --reuse-key which will cause the same key to be - used in the certificate when the lineage is renewed rather than generating a - new key. -* You can now add multiple email addresses to your ACME account with Certbot by - providing a comma separated list of emails to the --email flag. -* Support for Let's Encrypt's upcoming TLS-ALPN-01 challenge was added to acme. - For more information, see - https://community.letsencrypt.org/t/tls-alpn-validation-method/63814/1. -* acme now supports specifying the source address to bind to when sending - outgoing connections. You still cannot specify this address using Certbot. -* If you run Certbot against Let's Encrypt's ACMEv2 staging server but don't - already have an account registered at that server URL, Certbot will - automatically reuse your staging account from Let's Encrypt's ACMEv1 endpoint - if it exists. -* Interfaces were added to Certbot allowing plugins to be called at additional - points. The `GenericUpdater` interface allows plugins to perform actions - every time `certbot renew` is run, regardless of whether any certificates are - due for renewal, and the `RenewDeployer` interface allows plugins to perform - actions when a certificate is renewed. See `certbot.interfaces` for more - information. - -### Changed - -* When running Certbot with --dry-run and you don't already have a staging - account, the created account does not contain an email address even if one - was provided to avoid expiration emails from Let's Encrypt's staging server. -* certbot-nginx does a better job of automatically detecting the location of - Nginx's configuration files when run on BSD based systems. -* acme now requires and uses pytest when running tests with setuptools with - `python setup.py test`. -* `certbot config_changes` no longer waits for user input before exiting. - -### Fixed - -* Misleading log output that caused users to think that Certbot's standalone - plugin failed to bind to a port when performing a challenge has been - corrected. -* An issue where certbot-nginx would fail to enable HSTS if the server block - already had an `add_header` directive has been resolved. -* certbot-nginx now does a better job detecting the server block to base the - configuration for TLS-SNI challenges on. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -packages with functional changes were: - -* acme -* certbot -* certbot-apache -* certbot-nginx - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/54?closed=1 - -## 0.24.0 - 2018-05-02 - -### Added - -* certbot now has an enhance subcommand which allows you to configure security - enhancements like HTTP to HTTPS redirects, OCSP stapling, and HSTS without - reinstalling a certificate. -* certbot-dns-rfc2136 now allows the user to specify the port to use to reach - the DNS server in its credentials file. -* acme now parses the wildcard field included in authorizations so it can be - used by users of the library. - -### Changed - -* certbot-dns-route53 used to wait for each DNS update to propagate before - sending the next one, but now it sends all updates before waiting which - speeds up issuance for multiple domains dramatically. -* Certbot's official Docker images are now based on Alpine Linux 3.7 rather - than 3.4 because 3.4 has reached its end-of-life. -* We've doubled the time Certbot will spend polling authorizations before - timing out. -* The level of the message logged when Certbot is being used with - non-standard paths warning that crontabs for renewal included in Certbot - packages from OS package managers may not work has been reduced. This stops - the message from being written to stderr every time `certbot renew` runs. - -### Fixed - -* certbot-auto now works with Python 3.6. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -packages with changes other than their version number were: - -* acme -* certbot -* certbot-apache -* certbot-dns-digitalocean (only style improvements to tests) -* certbot-dns-rfc2136 - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/52?closed=1 - -## 0.23.0 - 2018-04-04 - -### Added - -* Support for OpenResty was added to the Nginx plugin. - -### Changed - -* The timestamps in Certbot's logfiles now use the system's local time zone - rather than UTC. -* Certbot's DNS plugins that use Lexicon now rely on Lexicon>=2.2.1 to be able - to create and delete multiple TXT records on a single domain. -* certbot-dns-google's test suite now works without an internet connection. - -### Fixed - -* Removed a small window that if during which an error occurred, Certbot - wouldn't clean up performed challenges. -* The parameters `default` and `ipv6only` are now removed from `listen` - directives when creating a new server block in the Nginx plugin. -* `server_name` directives enclosed in quotation marks in Nginx are now properly - supported. -* Resolved an issue preventing the Apache plugin from starting Apache when it's - not currently running on RHEL and Gentoo based systems. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -packages with changes other than their version number were: - -* certbot -* certbot-apache -* certbot-dns-cloudxns -* certbot-dns-dnsimple -* certbot-dns-dnsmadeeasy -* certbot-dns-google -* certbot-dns-luadns -* certbot-dns-nsone -* certbot-dns-rfc2136 -* certbot-nginx - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/50?closed=1 - -## 0.22.2 - 2018-03-19 - -### Fixed - -* A type error introduced in 0.22.1 that would occur during challenge cleanup - when a Certbot plugin raises an exception while trying to complete the - challenge was fixed. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -packages with changes other than their version number were: - -* certbot - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/53?closed=1 - -## 0.22.1 - 2018-03-19 - -### Changed - -* The ACME server used with Certbot's --dry-run and --staging flags is now - Let's Encrypt's ACMEv2 staging server which allows people to also test ACMEv2 - features with these flags. - -### Fixed - -* The HTTP Content-Type header is now set to the correct value during - certificate revocation with new versions of the ACME protocol. -* When using Certbot with Let's Encrypt's ACMEv2 server, it would add a blank - line to the top of chain.pem and between the certificates in fullchain.pem - for each lineage. These blank lines have been removed. -* Resolved a bug that caused Certbot's --allow-subset-of-names flag not to - work. -* Fixed a regression in acme.client.Client that caused the class to not work - when it was initialized without a ClientNetwork which is done by some of the - other projects using our ACME library. - -Despite us having broken lockstep, we are continuing to release new versions of -all Certbot components during releases for the time being, however, the only -packages with changes other than their version number were: - -* acme -* certbot - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/51?closed=1 - -## 0.22.0 - 2018-03-07 - -### Added - -* Support for obtaining wildcard certificates and a newer version of the ACME - protocol such as the one implemented by Let's Encrypt's upcoming ACMEv2 - endpoint was added to Certbot and its ACME library. Certbot still works with - older ACME versions and will automatically change the version of the protocol - used based on the version the ACME CA implements. -* The Apache and Nginx plugins are now able to automatically install a wildcard - certificate to multiple virtual hosts that you select from your server - configuration. -* The `certbot install` command now accepts the `--cert-name` flag for - selecting a certificate. -* `acme.client.BackwardsCompatibleClientV2` was added to Certbot's ACME library - which automatically handles most of the differences between new and old ACME - versions. `acme.client.ClientV2` is also available for people who only want - to support one version of the protocol or want to handle the differences - between versions themselves. -* certbot-auto now supports the flag --install-only which has the script - install Certbot and its dependencies and exit without invoking Certbot. -* Support for issuing a single certificate for a wildcard and base domain was - added to our Google Cloud DNS plugin. To do this, we now require your API - credentials have additional permissions, however, your credentials will - already have these permissions unless you defined a custom role with fewer - permissions than the standard DNS administrator role provided by Google. - These permissions are also only needed for the case described above so it - will continue to work for existing users. For more information about the - permissions changes, see the documentation in the plugin. - -### Changed - -* We have broken lockstep between our ACME library, Certbot, and its plugins. - This means that the different components do not need to be the same version - to work together like they did previously. This makes packaging easier - because not every piece of Certbot needs to be repackaged to ship a change to - a subset of its components. -* Support for Python 2.6 and Python 3.3 has been removed from ACME, Certbot, - Certbot's plugins, and certbot-auto. If you are using certbot-auto on a RHEL - 6 based system, it will walk you through the process of installing Certbot - with Python 3 and refuse to upgrade to a newer version of Certbot until you - have done so. -* Certbot's components now work with older versions of setuptools to simplify - packaging for EPEL 7. - -### Fixed - -* Issues caused by Certbot's Nginx plugin adding multiple ipv6only directives - has been resolved. -* A problem where Certbot's Apache plugin would add redundant include - directives for the TLS configuration managed by Certbot has been fixed. -* Certbot's webroot plugin now properly deletes any directories it creates. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/48?closed=1 - -## 0.21.1 - 2018-01-25 - -### Fixed - -* When creating an HTTP to HTTPS redirect in Nginx, we now ensure the Host - header of the request is set to an expected value before redirecting users to - the domain found in the header. The previous way Certbot configured Nginx - redirects was a potential security issue which you can read more about at - https://community.letsencrypt.org/t/security-issue-with-redirects-added-by-certbots-nginx-plugin/51493. -* Fixed a problem where Certbot's Apache plugin could fail HTTP-01 challenges - if basic authentication is configured for the domain you request a - certificate for. -* certbot-auto --no-bootstrap now properly tries to use Python 3.4 on RHEL 6 - based systems rather than Python 2.6. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/49?closed=1 - -## 0.21.0 - 2018-01-17 - -### Added - -* Support for the HTTP-01 challenge type was added to our Apache and Nginx - plugins. For those not aware, Let's Encrypt disabled the TLS-SNI-01 challenge - type which was what was previously being used by our Apache and Nginx plugins - last week due to a security issue. For more information about Let's Encrypt's - change, click - [here](https://community.letsencrypt.org/t/2018-01-11-update-regarding-acme-tls-sni-and-shared-hosting-infrastructure/50188). - Our Apache and Nginx plugins will automatically switch to use HTTP-01 so no - changes need to be made to your Certbot configuration, however, you should - make sure your server is accessible on port 80 and isn't behind an external - proxy doing things like redirecting all traffic from HTTP to HTTPS. HTTP to - HTTPS redirects inside Apache and Nginx are fine. -* IPv6 support was added to the Nginx plugin. -* Support for automatically creating server blocks based on the default server - block was added to the Nginx plugin. -* The flags --delete-after-revoke and --no-delete-after-revoke were added - allowing users to control whether the revoke subcommand also deletes the - certificates it is revoking. - -### Changed - -* We deprecated support for Python 2.6 and Python 3.3 in Certbot and its ACME - library. Support for these versions of Python will be removed in the next - major release of Certbot. If you are using certbot-auto on a RHEL 6 based - system, it will guide you through the process of installing Python 3. -* We split our implementation of JOSE (Javascript Object Signing and - Encryption) out of our ACME library and into a separate package named josepy. - This package is available on [PyPI](https://pypi.python.org/pypi/josepy) and - on [GitHub](https://github.com/certbot/josepy). -* We updated the ciphersuites used in Apache to the new [values recommended by - Mozilla](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29). - The major change here is adding ChaCha20 to the list of supported - ciphersuites. - -### Fixed - -* An issue with our Apache plugin on Gentoo due to differences in their - apache2ctl command have been resolved. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/47?closed=1 - -## 0.20.0 - 2017-12-06 - -### Added - -* Certbot's ACME library now recognizes URL fields in challenge objects in - preparation for Let's Encrypt's new ACME endpoint. The value is still - accessible in our ACME library through the name "uri". - -### Changed - -* The Apache plugin now parses some distro specific Apache configuration files - on non-Debian systems allowing it to get a clearer picture on the running - configuration. Internally, these changes were structured so that external - contributors can easily write patches to make the plugin work in new Apache - configurations. -* Certbot better reports network failures by removing information about - connection retries from the error output. -* An unnecessary question when using Certbot's webroot plugin interactively has - been removed. - -### Fixed - -* Certbot's NGINX plugin no longer sometimes incorrectly reports that it was - unable to deploy a HTTP->HTTPS redirect when requesting Certbot to enable a - redirect for multiple domains. -* Problems where the Apache plugin was failing to find directives and - duplicating existing directives on openSUSE have been resolved. -* An issue running the test shipped with Certbot and some our DNS plugins with - older versions of mock have been resolved. -* On some systems, users reported strangely interleaved output depending on - when stdout and stderr were flushed. This problem was resolved by having - Certbot regularly flush these streams. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/44?closed=1 - -## 0.19.0 - 2017-10-04 - -### Added - -* Certbot now has renewal hook directories where executable files can be placed - for Certbot to run with the renew subcommand. Pre-hooks, deploy-hooks, and - post-hooks can be specified in the renewal-hooks/pre, renewal-hooks/deploy, - and renewal-hooks/post directories respectively in Certbot's configuration - directory (which is /etc/letsencrypt by default). Certbot will automatically - create these directories when it is run if they do not already exist. -* After revoking a certificate with the revoke subcommand, Certbot will offer - to delete the lineage associated with the certificate. When Certbot is run - with --non-interactive, it will automatically try to delete the associated - lineage. -* When using Certbot's Google Cloud DNS plugin on Google Compute Engine, you no - longer have to provide a credential file to Certbot if you have configured - sufficient permissions for the instance which Certbot can automatically - obtain using Google's metadata service. - -### Changed - -* When deleting certificates interactively using the delete subcommand, Certbot - will now allow you to select multiple lineages to be deleted at once. -* Certbot's Apache plugin no longer always parses Apache's sites-available on - Debian based systems and instead only parses virtual hosts included in your - Apache configuration. You can provide an additional directory for Certbot to - parse using the command line flag --apache-vhost-root. - -### Fixed - -* The plugins subcommand can now be run without root access. -* certbot-auto now includes a timeout when updating itself so it no longer - hangs indefinitely when it is unable to connect to the external server. -* An issue where Certbot's Apache plugin would sometimes fail to deploy a - certificate on Debian based systems if mod_ssl wasn't already enabled has - been resolved. -* A bug in our Docker image where the certificates subcommand could not report - if certificates maintained by Certbot had been revoked has been fixed. -* Certbot's RFC 2136 DNS plugin (for use with software like BIND) now properly - performs DNS challenges when the domain being verified contains a CNAME - record. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/43?closed=1 - -## 0.18.2 - 2017-09-20 - -### Fixed - -* An issue where Certbot's ACME module would raise an AttributeError trying to - create self-signed certificates when used with pyOpenSSL 17.3.0 has been - resolved. For Certbot users with this version of pyOpenSSL, this caused - Certbot to crash when performing a TLS SNI challenge or when the Nginx plugin - tried to create an SSL server block. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/46?closed=1 - -## 0.18.1 - 2017-09-08 - -### Fixed - -* If certbot-auto was running as an unprivileged user and it upgraded from - 0.17.0 to 0.18.0, it would crash with a permissions error and would need to - be run again to successfully complete the upgrade. This has been fixed and - certbot-auto should upgrade cleanly to 0.18.1. -* Certbot usually uses "certbot-auto" or "letsencrypt-auto" in error messages - and the User-Agent string instead of "certbot" when you are using one of - these wrapper scripts. Proper detection of this was broken with Certbot's new - installation path in /opt in 0.18.0 but this problem has been resolved. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/45?closed=1 - -## 0.18.0 - 2017-09-06 - -### Added - -* The Nginx plugin now configures Nginx to use 2048-bit Diffie-Hellman - parameters. Java 6 clients do not support Diffie-Hellman parameters larger - than 1024 bits, so if you need to support these clients you will need to - manually modify your Nginx configuration after using the Nginx installer. - -### Changed - -* certbot-auto now installs Certbot in directories under `/opt/eff.org`. If you - had an existing installation from certbot-auto, a symlink is created to the - new directory. You can configure certbot-auto to use a different path by - setting the environment variable VENV_PATH. -* The Nginx plugin can now be selected in Certbot's interactive output. -* Output verbosity of renewal failures when running with `--quiet` has been - reduced. -* The default revocation reason shown in Certbot help output now is a human - readable string instead of a numerical code. -* Plugin selection is now included in normal terminal output. - -### Fixed - -* A newer version of ConfigArgParse is now installed when using certbot-auto - causing values set to false in a Certbot INI configuration file to be handled - intuitively. Setting a boolean command line flag to false is equivalent to - not including it in the configuration file at all. -* New naming conventions preventing certbot-auto from installing OS - dependencies on Fedora 26 have been resolved. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/42?closed=1 - -## 0.17.0 - 2017-08-02 - -### Added - -* Support in our nginx plugin for modifying SSL server blocks that do - not contain certificate or key directives. -* A `--max-log-backups` flag to allow users to configure or even completely - disable Certbot's built in log rotation. -* A `--user-agent-comment` flag to allow people who build tools around Certbot - to differentiate their user agent string by adding a comment to its default - value. - -### Changed - -* Due to some awesome work by - [cryptography project](https://github.com/pyca/cryptography), compilation can - now be avoided on most systems when using certbot-auto. This eliminates many - problems people have had in the past such as running out of memory, having - invalid headers/libraries, and changes to the OS packages on their system - after compilation breaking Certbot. -* The `--renew-hook` flag has been hidden in favor of `--deploy-hook`. This new - flag works exactly the same way except it is always run when a certificate is - issued rather than just when it is renewed. -* We have started printing deprecation warnings in certbot-auto for - experimentally supported systems with OS packages available. -* A certificate lineage's name is included in error messages during renewal. - -### Fixed - -* Encoding errors that could occur when parsing error messages from the ACME - server containing Unicode have been resolved. -* certbot-auto no longer prints misleading messages about there being a newer - pip version available when installation fails. -* Certbot's ACME library now properly extracts domains from critical SAN - extensions. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.17.0+is%3Aclosed - -## 0.16.0 - 2017-07-05 - -### Added - -* A plugin for performing DNS challenges using dynamic DNS updates as defined - in RFC 2316. This plugin is packaged separately from Certbot and is available - at https://pypi.python.org/pypi/certbot-dns-rfc2136. It supports Python 2.6, - 2.7, and 3.3+. At this time, there isn't a good way to install this plugin - when using certbot-auto, but this should change in the near future. -* Plugins for performing DNS challenges for the providers - [DNS Made Easy](https://pypi.python.org/pypi/certbot-dns-dnsmadeeasy) and - [LuaDNS](https://pypi.python.org/pypi/certbot-dns-luadns). These plugins are - packaged separately from Certbot and support Python 2.7 and 3.3+. Currently, - there isn't a good way to install these plugins when using certbot-auto, - but that should change soon. -* Support for performing TLS-SNI-01 challenges when using the manual plugin. -* Automatic detection of Arch Linux in the Apache plugin providing better - default settings for the plugin. - -### Changed - -* The text of the interactive question about whether a redirect from HTTP to - HTTPS should be added by Certbot has been rewritten to better explain the - choices to the user. -* Simplified HTTP challenge instructions in the manual plugin. - -### Fixed - -* Problems performing a dry run when using the Nginx plugin have been fixed. -* Resolved an issue where certbot-dns-digitalocean's test suite would sometimes - fail when ran using Python 3. -* On some systems, previous versions of certbot-auto would error out with a - message about a missing hash for setuptools. This has been fixed. -* A bug where Certbot would sometimes not print a space at the end of an - interactive prompt has been resolved. -* Nonfatal tracebacks are no longer shown in rare cases where Certbot - encounters an exception trying to close its TCP connection with the ACME - server. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.16.0+is%3Aclosed - -## 0.15.0 - 2017-06-08 - -### Added - -* Plugins for performing DNS challenges for popular providers. Like the Apache - and Nginx plugins, these plugins are packaged separately and not included in - Certbot by default. So far, we have plugins for - [Amazon Route 53](https://pypi.python.org/pypi/certbot-dns-route53), - [Cloudflare](https://pypi.python.org/pypi/certbot-dns-cloudflare), - [DigitalOcean](https://pypi.python.org/pypi/certbot-dns-digitalocean), and - [Google Cloud](https://pypi.python.org/pypi/certbot-dns-google) which all - work on Python 2.6, 2.7, and 3.3+. Additionally, we have plugins for - [CloudXNS](https://pypi.python.org/pypi/certbot-dns-cloudxns), - [DNSimple](https://pypi.python.org/pypi/certbot-dns-dnsimple), - [NS1](https://pypi.python.org/pypi/certbot-dns-nsone) which work on Python - 2.7 and 3.3+ (and not 2.6). Currently, there isn't a good way to install - these plugins when using `certbot-auto`, but that should change soon. -* IPv6 support in the standalone plugin. When performing a challenge, the - standalone plugin automatically handles listening for IPv4/IPv6 traffic based - on the configuration of your system. -* A mechanism for keeping your Apache and Nginx SSL/TLS configuration up to - date. When the Apache or Nginx plugins are used, they place SSL/TLS - configuration options in the root of Certbot's config directory - (`/etc/letsencrypt` by default). Now when a new version of these plugins run - on your system, they will automatically update the file to the newest - version if it is unmodified. If you manually modified the file, Certbot will - display a warning giving you a path to the updated file which you can use as - a reference to manually update your modified copy. -* `--http-01-address` and `--tls-sni-01-address` flags for controlling the - address Certbot listens on when using the standalone plugin. -* The command `certbot certificates` that lists certificates managed by Certbot - now performs additional validity checks to notify you if your files have - become corrupted. - -### Changed - -* Messages custom hooks print to `stdout` are now displayed by Certbot when not - running in `--quiet` mode. -* `jwk` and `alg` fields in JWS objects have been moved into the protected - header causing Certbot to more closely follow the latest version of the ACME - spec. - -### Fixed - -* Permissions on renewal configuration files are now properly preserved when - they are updated. -* A bug causing Certbot to display strange defaults in its help output when - using Python <= 2.7.4 has been fixed. -* Certbot now properly handles mixed case domain names found in custom CSRs. -* A number of poorly worded prompts and error messages. - -### Removed - -* Support for OpenSSL 1.0.0 in `certbot-auto` has been removed as we now pin a - newer version of `cryptography` which dropped support for this version. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.15.0+is%3Aclosed - -## 0.14.2 - 2017-05-25 - -### Fixed - -* Certbot 0.14.0 included a bug where Certbot would create a temporary log file -(usually in /tmp) if the program exited during argument parsing. If a user -provided -h/--help/help, --version, or an invalid command line argument, -Certbot would create this temporary log file. This was especially bothersome to -certbot-auto users as certbot-auto runs `certbot --version` internally to see -if the script needs to upgrade causing it to create at least one of these files -on every run. This problem has been resolved. - -More details about this change can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.14.2+is%3Aclosed - -## 0.14.1 - 2017-05-16 - -### Fixed - -* Certbot now works with configargparse 0.12.0. -* Issues with the Apache plugin and Augeas 1.7+ have been resolved. -* A problem where the Nginx plugin would fail to install certificates on -systems that had the plugin's SSL/TLS options file from 7+ months ago has been -fixed. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.14.1+is%3Aclosed - -## 0.14.0 - 2017-05-04 - -### Added - -* Python 3.3+ support for all Certbot packages. `certbot-auto` still currently -only supports Python 2, but the `acme`, `certbot`, `certbot-apache`, and -`certbot-nginx` packages on PyPI now fully support Python 2.6, 2.7, and 3.3+. -* Certbot's Apache plugin now handles multiple virtual hosts per file. -* Lockfiles to prevent multiple versions of Certbot running simultaneously. - -### Changed - -* When converting an HTTP virtual host to HTTPS in Apache, Certbot only copies -the virtual host rather than the entire contents of the file it's contained -in. -* The Nginx plugin now includes SSL/TLS directives in a separate file located -in Certbot's configuration directory rather than copying the contents of the -file into every modified `server` block. - -### Fixed - -* Ensure logging is configured before parts of Certbot attempt to log any -messages. -* Support for the `--quiet` flag in `certbot-auto`. -* Reverted a change made in a previous release to make the `acme` and `certbot` -packages always depend on `argparse`. This dependency is conditional again on -the user's Python version. -* Small bugs in the Nginx plugin such as properly handling empty `server` -blocks and setting `server_names_hash_bucket_size` during challenges. - -As always, a more complete list of changes can be found on GitHub: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.14.0+is%3Aclosed - -## 0.13.0 - 2017-04-06 - -### Added - -* `--debug-challenges` now pauses Certbot after setting up challenges for debugging. -* The Nginx parser can now handle all valid directives in configuration files. -* Nginx ciphersuites have changed to Mozilla Intermediate. -* `certbot-auto --no-bootstrap` provides the option to not install OS dependencies. - -### Fixed - -* `--register-unsafely-without-email` now respects `--quiet`. -* Hyphenated renewal parameters are now saved in renewal config files. -* `--dry-run` no longer persists keys and csrs. -* Certbot no longer hangs when trying to start Nginx in Arch Linux. -* Apache rewrite rules no longer double-encode characters. - -A full list of changes is available on GitHub: -https://github.com/certbot/certbot/issues?q=is%3Aissue%20milestone%3A0.13.0%20is%3Aclosed%20 - -## 0.12.0 - 2017-03-02 - -### Added - -* Certbot now allows non-camelcase Apache VirtualHost names. -* Certbot now allows more log messages to be silenced. - -### Fixed - -* Fixed a regression around using `--cert-name` when getting new certificates - -More information about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue%20milestone%3A0.12.0 - -## 0.11.1 - 2017-02-01 - -### Fixed - -* Resolved a problem where Certbot would crash while parsing command line -arguments in some cases. -* Fixed a typo. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/pulls?q=is%3Apr%20milestone%3A0.11.1%20is%3Aclosed - -## 0.11.0 - 2017-02-01 - -### Added - -* When using the standalone plugin while running Certbot interactively -and a required port is bound by another process, Certbot will give you -the option to retry to grab the port rather than immediately exiting. -* You are now able to deactivate your account with the Let's Encrypt -server using the `unregister` subcommand. -* When revoking a certificate using the `revoke` subcommand, you now -have the option to provide the reason the certificate is being revoked -to Let's Encrypt with `--reason`. - -### Changed - -* Providing `--quiet` to `certbot-auto` now silences package manager output. - -### Removed - -* Removed the optional `dnspython` dependency in our `acme` package. -Now the library does not support client side verification of the DNS -challenge. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.11.0+is%3Aclosed - -## 0.10.2 - 2017-01-25 - -### Added - -* If Certbot receives a request with a `badNonce` error, it now -automatically retries the request. Since nonces from Let's Encrypt expire, -this helps people performing the DNS challenge with the `manual` plugin -who may have to wait an extended period of time for their DNS changes to -propagate. - -### Fixed - -* Certbot now saves the `--preferred-challenges` values for renewal. Previously -these values were discarded causing a different challenge type to be used when -renewing certs in some cases. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.2+is%3Aclosed - -## 0.10.1 - 2017-01-13 - -### Fixed - -* Resolve problems where when asking Certbot to update a certificate at -an existing path to include different domain names, the old names would -continue to be used. -* Fix issues successfully running our unit test suite on some systems. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.1+is%3Aclosed - -## 0.10.0 - 2017-01-11 - -## Added - -* Added the ability to customize and automatically complete DNS and HTTP -domain validation challenges with the manual plugin. The flags -`--manual-auth-hook` and `--manual-cleanup-hook` can now be provided -when using the manual plugin to execute commands provided by the user to -perform and clean up challenges provided by the CA. This is best used in -complicated setups where the DNS challenge must be used or Certbot's -existing plugins cannot be used to perform HTTP challenges. For more -information on how this works, see `certbot --help manual`. -* Added a `--cert-name` flag for specifying the name to use for the -certificate in Certbot's configuration directory. Using this flag in -combination with `-d/--domains`, a user can easily request a new -certificate with different domains and save it with the name provided by -`--cert-name`. Additionally, `--cert-name` can be used to select a -certificate with the `certonly` and `run` subcommands so a full list of -domains in the certificate does not have to be provided. -* Added subcommand `certificates` for listing the certificates managed by -Certbot and their properties. -* Added the `delete` subcommand for removing certificates managed by Certbot -from the configuration directory. -* Certbot now supports requesting internationalized domain names (IDNs). -* Hooks provided to Certbot are now saved to be reused during renewal. -If you run Certbot with `--pre-hook`, `--renew-hook`, or `--post-hook` -flags when obtaining a certificate, the provided commands will -automatically be saved and executed again when renewing the certificate. -A pre-hook and/or post-hook can also be given to the `certbot renew` -command either on the command line or in a [configuration -file](https://certbot.eff.org/docs/using.html#configuration-file) to run -an additional command before/after any certificate is renewed. Hooks -will only be run if a certificate is renewed. -* Support Busybox in certbot-auto. - -### Changed - -* Recategorized `-h/--help` output to improve documentation and -discoverability. - -### Removed - -* Removed the ncurses interface. This change solves problems people -were having on many systems, reduces the number of Certbot -dependencies, and simplifies our code. Certbot's only interface now is -the text interface which was available by providing `-t/--text` to -earlier versions of Certbot. - -### Fixed - -* Many small bug fixes. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.0is%3Aclosed - -## 0.9.3 - 2016-10-13 - -### Added - -* The Apache plugin uses information about your OS to help determine the -layout of your Apache configuration directory. We added a patch to -ensure this code behaves the same way when testing on different systems -as the tests were failing in some cases. - -### Changed - -* Certbot adopted more conservative behavior about reporting a needed port as -unavailable when using the standalone plugin. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/27?closed=1 - -## 0.9.2 - 2016-10-12 - -### Added - -* Certbot stopped requiring that all possibly required ports are available when -using the standalone plugin. It now only verifies that the ports are available -when they are necessary. - -### Fixed - -* Certbot now verifies that our optional dependencies version matches what is -required by Certbot. -* Certnot now properly copies the `ssl on;` directives as necessary when -performing domain validation in the Nginx plugin. -* Fixed problem where symlinks were becoming files when they were -packaged, causing errors during testing and OS packaging. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/26?closed=1 - -## 0.9.1 - 2016-10-06 - -### Fixed - -* Fixed a bug that was introduced in version 0.9.0 where the command -line flag -q/--quiet wasn't respected in some cases. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/milestone/25?closed=1 - -## 0.9.0 - 2016-10-05 - -### Added - -* Added an alpha version of the Nginx plugin. This plugin fully automates the -process of obtaining and installing certificates with Nginx. -Additionally, it is able to automatically configure security -enhancements such as an HTTP to HTTPS redirect and OCSP stapling. To use -this plugin, you must have the `certbot-nginx` package installed (which -is installed automatically when using `certbot-auto`) and provide -`--nginx` on the command line. This plugin is still in its early stages -so we recommend you use it with some caution and make sure you have a -backup of your Nginx configuration. -* Added support for the `DNS` challenge in the `acme` library and `DNS` in -Certbot's `manual` plugin. This allows you to create DNS records to -prove to Let's Encrypt you control the requested domain name. To use -this feature, include `--manual --preferred-challenges dns` on the -command line. -* Certbot now helps with enabling Extra Packages for Enterprise Linux (EPEL) on -CentOS 6 when using `certbot-auto`. To use `certbot-auto` on CentOS 6, -the EPEL repository has to be enabled. `certbot-auto` will now prompt -users asking them if they would like the script to enable this for them -automatically. This is done without prompting users when using -`letsencrypt-auto` or if `-n/--non-interactive/--noninteractive` is -included on the command line. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.9.0+is%3Aclosed - -## 0.8.1 - 2016-06-14 - -### Added - -* Certbot now preserves a certificate's common name when using `renew`. -* Certbot now saves webroot values for renewal when they are entered interactively. -* Certbot now gracefully reports that the Apache plugin isn't usable when Augeas is not installed. -* Added experimental support for Mageia has been added to `certbot-auto`. - -### Fixed - -* Fixed problems with an invalid user-agent string on OS X. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.8.1+ - -## 0.8.0 - 2016-06-02 - -### Added - -* Added the `register` subcommand which can be used to register an account -with the Let's Encrypt CA. -* You can now run `certbot register --update-registration` to -change the e-mail address associated with your registration. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.8.0+ - -## 0.7.0 - 2016-05-27 - -### Added - -* Added `--must-staple` to request certificates from Let's Encrypt -with the OCSP must staple extension. -* Certbot now automatically configures OSCP stapling for Apache. -* Certbot now allows requesting certificates for domains found in the common name -of a custom CSR. - -### Fixed - -* Fixed a number of miscellaneous bugs - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=milestone%3A0.7.0+is%3Aissue - -## 0.6.0 - 2016-05-12 - -### Added - -* Versioned the datetime dependency in setup.py. - -### Changed - -* Renamed the client from `letsencrypt` to `certbot`. - -### Fixed - -* Fixed a small json deserialization error. -* Certbot now preserves domain order in generated CSRs. -* Fixed some minor bugs. - -More details about these changes can be found on our GitHub repo: -https://github.com/certbot/certbot/issues?q=is%3Aissue%20milestone%3A0.6.0%20is%3Aclosed%20 - -## 0.5.0 - 2016-04-05 - -### Added - -* Added the ability to use the webroot plugin interactively. -* Added the flags --pre-hook, --post-hook, and --renew-hook which can be used with -the renew subcommand to register shell commands to run in response to -renewal events. Pre-hook commands will be run before any certs are -renewed, post-hook commands will be run after any certs are renewed, -and renew-hook commands will be run after each cert is renewed. If no -certs are due for renewal, no command is run. -* Added a -q/--quiet flag which silences all output except errors. -* Added an --allow-subset-of-domains flag which can be used with the renew -command to prevent renewal failures for a subset of the requested -domains from causing the client to exit. - -### Changed - -* Certbot now uses renewal configuration files. In /etc/letsencrypt/renewal -by default, these files can be used to control what parameters are -used when renewing a specific certificate. - -More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.5.0+is%3Aissue - -## 0.4.2 - 2016-03-03 - -### Fixed - -* Resolved problems encountered when compiling letsencrypt -against the new OpenSSL release. -* Fixed problems encountered when using `letsencrypt renew` with configuration files -from the private beta. - -More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.2 - -## 0.4.1 - 2016-02-29 - -### Fixed - -* Fixed Apache parsing errors encountered with some configurations. -* Fixed Werkzeug dependency problems encountered on some Red Hat systems. -* Fixed bootstrapping failures when using letsencrypt-auto with --no-self-upgrade. -* Fixed problems with parsing renewal config files from private beta. - -More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is:issue+milestone:0.4.1 - -## 0.4.0 - 2016-02-10 - -### Added - -* Added the verb/subcommand `renew` which can be used to renew your existing -certificates as they approach expiration. Running `letsencrypt renew` -will examine all existing certificate lineages and determine if any are -less than 30 days from expiration. If so, the client will use the -settings provided when you previously obtained the certificate to renew -it. The subcommand finishes by printing a summary of which renewals were -successful, failed, or not yet due. -* Added a `--dry-run` flag to help with testing configuration -without affecting production rate limits. Currently supported by the -`renew` and `certonly` subcommands, providing `--dry-run` on the command -line will obtain certificates from the staging server without saving the -resulting certificates to disk. -* Added major improvements to letsencrypt-auto. This script -has been rewritten to include full support for Python 2.6, the ability -for letsencrypt-auto to update itself, and improvements to the -stability, security, and performance of the script. -* Added support for Apache 2.2 to the Apache plugin. - -More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.0 - -## 0.3.0 - 2016-01-27 - -### Added - -* Added a non-interactive mode which can be enabled by including `-n` or -`--non-interactive` on the command line. This can be used to guarantee -the client will not prompt when run automatically using cron/systemd. -* Added preparation for the new letsencrypt-auto script. Over the past -couple months, we've been working on increasing the reliability and -security of letsencrypt-auto. A number of changes landed in this -release to prepare for the new version of this script. - -More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.3.0 - -## 0.2.0 - 2016-01-14 - -### Added - -* Added Apache plugin support for non-Debian based systems. Support has been -added for modern Red Hat based systems such as Fedora 23, Red Hat 7, -and CentOS 7 running Apache 2.4. In theory, this plugin should be -able to be configured to run on any Unix-like OS running Apache 2.4. -* Relaxed PyOpenSSL version requirements. This adds support for systems -with PyOpenSSL versions 0.13 or 0.14. -* Improved error messages from the client. - -### Fixed - -* Resolved issues with the Apache plugin enabling an HTTP to HTTPS -redirect on some systems. - -More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.2.0 - -## 0.1.1 - 2015-12-15 - -### Added - -* Added a check that avoids attempting to issue for unqualified domain names like -"localhost". - -### Fixed - -* Fixed a confusing UI path that caused some users to repeatedly renew -their certs while experimenting with the client, in some cases hitting -issuance rate limits. -* Fixed numerous Apache configuration parser problems -* Fixed --webroot permission handling for non-root users - -More details about these changes can be found on our GitHub repo: -https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.1.1 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 120000 index 000000000..ba7396f24 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +certbot/CHANGELOG.md \ No newline at end of file diff --git a/Dockerfile-dev b/Dockerfile-dev index 86f5f04e7..ae197b1cb 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -6,16 +6,15 @@ EXPOSE 80 443 WORKDIR /opt/certbot/src -# TODO: Install Apache/Nginx for plugin development. COPY . . RUN apt-get update && \ - apt-get install apache2 git nginx-light -y && \ - letsencrypt-auto-source/letsencrypt-auto --os-packages-only && \ + apt-get install apache2 git python3-dev python3-venv gcc libaugeas0 \ + libssl-dev libffi-dev ca-certificates openssl nginx-light -y && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* \ /tmp/* \ /var/tmp/* -RUN VENV_NAME="../venv" python tools/venv.py +RUN VENV_NAME="../venv3" python3 tools/venv3.py -ENV PATH /opt/certbot/venv/bin:$PATH +ENV PATH /opt/certbot/venv3/bin:$PATH diff --git a/README.rst b/README.rst deleted file mode 100644 index 5f5ea17a1..000000000 --- a/README.rst +++ /dev/null @@ -1,131 +0,0 @@ -.. This file contains a series of comments that are used to include sections of this README in other files. Do not modify these comments unless you know what you are doing. tag:intro-begin - -Certbot is part of EFF’s effort to encrypt the entire Internet. Secure communication over the Web relies on HTTPS, which requires the use of a digital certificate that lets browsers verify the identity of web servers (e.g., is that really google.com?). Web servers obtain their certificates from trusted third parties called certificate authorities (CAs). Certbot is an easy-to-use client that fetches a certificate from Let’s Encrypt—an open certificate authority launched by the EFF, Mozilla, and others—and deploys it to a web server. - -Anyone who has gone through the trouble of setting up a secure website knows what a hassle getting and maintaining a certificate is. Certbot and Let’s Encrypt can automate away the pain and let you turn on and manage HTTPS with simple commands. Using Certbot and Let's Encrypt is free, so there’s no need to arrange payment. - -How you use Certbot depends on the configuration of your web server. The best way to get started is to use our `interactive guide `_. It generates instructions based on your configuration settings. In most cases, you’ll need `root or administrator access `_ to your web server to run Certbot. - -Certbot is meant to be run directly on your web server, not on your personal computer. If you’re using a hosted service and don’t have direct access to your web server, you might not be able to use Certbot. Check with your hosting provider for documentation about uploading certificates or using certificates issued by Let’s Encrypt. - -Certbot is a fully-featured, extensible client for the Let's -Encrypt CA (or any other CA that speaks the `ACME -`_ -protocol) that can automate the tasks of obtaining certificates and -configuring webservers to use them. This client runs on Unix-based operating -systems. - -To see the changes made to Certbot between versions please refer to our -`changelog `_. - -Until May 2016, Certbot was named simply ``letsencrypt`` or ``letsencrypt-auto``, -depending on install method. Instructions on the Internet, and some pieces of the -software, may still refer to this older name. - -Contributing ------------- - -If you'd like to contribute to this project please read `Developer Guide -`_. - -This project is governed by `EFF's Public Projects Code of Conduct `_. - -.. _installation: - -How to run the client ---------------------- - -The easiest way to install and run Certbot is by visiting `certbot.eff.org`_, -where you can find the correct instructions for many web server and OS -combinations. For more information, see `Get Certbot -`_. - -.. _certbot.eff.org: https://certbot.eff.org/ - -Understanding the client in more depth --------------------------------------- - -To understand what the client is doing in detail, it's important to -understand the way it uses plugins. Please see the `explanation of -plugins `_ in -the User Guide. - -Links -===== - -.. Do not modify this comment unless you know what you're doing. tag:links-begin - -Documentation: https://certbot.eff.org/docs - -Software project: https://github.com/certbot/certbot - -Notes for developers: https://certbot.eff.org/docs/contributing.html - -Main Website: https://certbot.eff.org - -Let's Encrypt Website: https://letsencrypt.org - -Community: https://community.letsencrypt.org - -ACME spec: http://ietf-wg-acme.github.io/acme/ - -ACME working area in github: https://github.com/ietf-wg-acme/acme - -|build-status| |coverage| |docs| |container| - -.. |build-status| image:: https://travis-ci.com/certbot/certbot.svg?branch=master - :target: https://travis-ci.com/certbot/certbot - :alt: Travis CI status - -.. |coverage| image:: https://codecov.io/gh/certbot/certbot/branch/master/graph/badge.svg - :target: https://codecov.io/gh/certbot/certbot - :alt: Coverage status - -.. |docs| image:: https://readthedocs.org/projects/letsencrypt/badge/ - :target: https://readthedocs.org/projects/letsencrypt/ - :alt: Documentation status - -.. |container| image:: https://quay.io/repository/letsencrypt/letsencrypt/status - :target: https://quay.io/repository/letsencrypt/letsencrypt - :alt: Docker Repository on Quay.io - -.. Do not modify this comment unless you know what you're doing. tag:links-end - -System Requirements -=================== - -See https://certbot.eff.org/docs/install.html#system-requirements. - -.. Do not modify this comment unless you know what you're doing. tag:intro-end - -.. Do not modify this comment unless you know what you're doing. tag:features-begin - -Current Features -===================== - -* Supports multiple web servers: - - - apache/2.x - - nginx/0.8.48+ - - webroot (adds files to webroot directories in order to prove control of - domains and obtain certs) - - standalone (runs its own simple webserver to prove you control a domain) - - other server software via `third party plugins `_ - -* The private key is generated locally on your system. -* Can talk to the Let's Encrypt CA or optionally to other ACME - compliant services. -* Can get domain-validated (DV) certificates. -* Can revoke certificates. -* Adjustable RSA key bit-length (2048 (default), 4096, ...). -* Can optionally install a http -> https redirect, so your site effectively - runs https only (Apache only) -* Fully automated. -* Configuration changes are logged and can be reverted. -* Supports an interactive text UI, or can be driven entirely from the - command line. -* Free and Open Source Software, made with Python. - -.. Do not modify this comment unless you know what you're doing. tag:features-end - -For extensive documentation on using and contributing to Certbot, go to https://certbot.eff.org/docs. If you would like to contribute to the project or run the latest code from git, you should read our `developer guide `_. diff --git a/README.rst b/README.rst new file mode 120000 index 000000000..645fd4c78 --- /dev/null +++ b/README.rst @@ -0,0 +1 @@ +certbot/README.rst \ No newline at end of file diff --git a/acme/MANIFEST.in b/acme/MANIFEST.in index 1619bef69..de254250e 100644 --- a/acme/MANIFEST.in +++ b/acme/MANIFEST.in @@ -3,4 +3,6 @@ include README.rst include pytest.ini recursive-include docs * recursive-include examples * -recursive-include acme/testdata * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/acme/acme/__init__.py b/acme/acme/__init__.py index 8a034470a..d1679fcad 100644 --- a/acme/acme/__init__.py +++ b/acme/acme/__init__.py @@ -13,7 +13,6 @@ import warnings # # It is based on # https://github.com/requests/requests/blob/1278ecdf71a312dc2268f3bfc0aabfab3c006dcf/requests/packages.py - import josepy as jose for mod in list(sys.modules): diff --git a/acme/acme/challenges.py b/acme/acme/challenges.py index f417bc47c..8a0366301 100644 --- a/acme/acme/challenges.py +++ b/acme/acme/challenges.py @@ -54,8 +54,7 @@ class UnrecognizedChallenge(Challenge): object.__setattr__(self, "jobj", jobj) def to_partial_json(self): - # pylint: disable=no-member - return self.jobj + return self.jobj # pylint: disable=no-member @classmethod def from_json(cls, jobj): @@ -113,7 +112,7 @@ class KeyAuthorizationChallengeResponse(ChallengeResponse): :rtype: bool """ - parts = self.key_authorization.split('.') # pylint: disable=no-member + parts = self.key_authorization.split('.') if len(parts) != 2: logger.debug("Key authorization (%r) is not well formed", self.key_authorization) @@ -231,7 +230,7 @@ class DNS01Response(KeyAuthorizationChallengeResponse): return verified -@Challenge.register # pylint: disable=too-many-ancestors +@Challenge.register class DNS01(KeyAuthorizationChallenge): """ACME dns-01 challenge.""" response_cls = DNS01Response @@ -321,7 +320,7 @@ class HTTP01Response(KeyAuthorizationChallengeResponse): return True -@Challenge.register # pylint: disable=too-many-ancestors +@Challenge.register class HTTP01(KeyAuthorizationChallenge): """ACME http-01 challenge.""" response_cls = HTTP01Response @@ -372,7 +371,7 @@ class TLSALPN01Response(KeyAuthorizationChallengeResponse): typ = "tls-alpn-01" -@Challenge.register # pylint: disable=too-many-ancestors +@Challenge.register class TLSALPN01(KeyAuthorizationChallenge): """ACME tls-alpn-01 challenge. diff --git a/acme/acme/client.py b/acme/acme/client.py index d2002576e..527430120 100644 --- a/acme/acme/client.py +++ b/acme/acme/client.py @@ -5,25 +5,26 @@ import datetime from email.utils import parsedate_tz import heapq import logging -import time import re import sys +import time -import six -from six.moves import http_client # pylint: disable=import-error import josepy as jose import OpenSSL 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 acme import crypto_util from acme import errors from acme import jws from acme import messages -# pylint: disable=unused-import, no-name-in-module -from acme.magic_typing import Dict, List, Set, Text - +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 logger = logging.getLogger(__name__) @@ -33,7 +34,6 @@ logger = logging.getLogger(__name__) # https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning if sys.version_info < (2, 7, 9): # pragma: no cover try: - # pylint: disable=no-member requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3() # type: ignore except AttributeError: import urllib3.contrib.pyopenssl # pylint: disable=import-error @@ -44,7 +44,7 @@ DEFAULT_NETWORK_TIMEOUT = 45 DER_CONTENT_TYPE = 'application/pkix-cert' -class ClientBase(object): # pylint: disable=too-many-instance-attributes +class ClientBase(object): """ACME client base object. :ivar messages.Directory directory: @@ -254,7 +254,6 @@ class Client(ClientBase): URI from which the resource will be downloaded. """ - # pylint: disable=too-many-arguments self.key = key if net is None: net = ClientNetwork(key, alg=alg, verify_ssl=verify_ssl) @@ -280,7 +279,6 @@ class Client(ClientBase): assert response.status_code == http_client.CREATED # "Instance of 'Field' has no key/contact member" bug: - # pylint: disable=no-member return self._regr_from_response(response) def query_registration(self, regr): @@ -435,7 +433,6 @@ class Client(ClientBase): was marked by the CA as invalid """ - # pylint: disable=too-many-locals assert max_attempts > 0 attempts = collections.defaultdict(int) # type: Dict[messages.AuthorizationResource, int] exhausted = set() @@ -466,7 +463,6 @@ class Client(ClientBase): updated[authzr] = updated_authzr attempts[authzr] += 1 - # pylint: disable=no-member if updated_authzr.body.status not in ( messages.STATUS_VALID, messages.STATUS_INVALID): if attempts[authzr] < max_attempts: @@ -607,7 +603,6 @@ class ClientV2(ClientBase): if response.status_code == 200 and 'Location' in response.headers: raise errors.ConflictError(response.headers.get('Location')) # "Instance of 'Field' has no key/contact member" bug: - # pylint: disable=no-member regr = self._regr_from_response(response) self.net.account = regr return regr @@ -731,7 +726,7 @@ class ClientV2(ClientBase): for authzr in responses: if authzr.body.status != messages.STATUS_VALID: for chall in authzr.body.challenges: - if chall.error != None: + if chall.error is not None: failed.append(authzr) if failed: raise errors.ValidationError(failed) @@ -781,29 +776,13 @@ class ClientV2(ClientBase): def _post_as_get(self, *args, **kwargs): """ - Send GET request using the POST-as-GET protocol if needed. - The request will be first issued using POST-as-GET for ACME v2. If the ACME CA servers do - not support this yet and return an error, request will be retried using GET. - For ACME v1, only GET request will be tried, as POST-as-GET is not supported. + Send GET request using the POST-as-GET protocol. :param args: :param kwargs: :return: """ - if self.acme_version >= 2: - # We add an empty payload for POST-as-GET requests - new_args = args[:1] + (None,) + args[1:] - try: - return self._post(*new_args, **kwargs) - except messages.Error as error: - if error.code == 'malformed': - logger.debug('Error during a POST-as-GET request, ' - 'your ACME CA server may not support it:\n%s', error) - logger.debug('Retrying request with GET.') - else: # pragma: no cover - raise - - # If POST-as-GET is not supported yet, we use a GET instead. - return self.net.get(*args, **kwargs) + new_args = args[:1] + (None,) + args[1:] + return self._post(*new_args, **kwargs) class BackwardsCompatibleClientV2(object): @@ -947,7 +926,7 @@ class BackwardsCompatibleClientV2(object): return self.client.external_account_required() -class ClientNetwork(object): # pylint: disable=too-many-instance-attributes +class ClientNetwork(object): """Wrapper around requests that signs POSTs for authentication. Also adds user agent, and handles Content-Type. @@ -973,7 +952,6 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes def __init__(self, key, account=None, alg=jose.RS256, verify_ssl=True, user_agent='acme-python', timeout=DEFAULT_NETWORK_TIMEOUT, source_address=None): - # pylint: disable=too-many-arguments self.key = key self.account = account self.alg = alg @@ -1081,7 +1059,6 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes return response def _send_request(self, method, url, *args, **kwargs): - # pylint: disable=too-many-locals """Send HTTP request. Makes sure that `verify_ssl` is respected. Logs request and @@ -1128,10 +1105,9 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes err_regex = r".*host='(\S*)'.*Max retries exceeded with url\: (\/\w*).*(\[Errno \d+\])([A-Za-z ]*)" m = re.match(err_regex, str(e)) if m is None: - raise # pragma: no cover - else: - host, path, _err_no, err_msg = m.groups() - raise ValueError("Requesting {0}{1}:{2}".format(host, path, err_msg)) + raise # pragma: no cover + host, path, _err_no, err_msg = m.groups() + raise ValueError("Requesting {0}{1}:{2}".format(host, path, err_msg)) # If content is DER, log the base64 of it instead of raw bytes, to keep # binary data out of the logs. @@ -1197,8 +1173,7 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes if error.code == 'badNonce': logger.debug('Retrying request after error:\n%s', error) return self._post_once(*args, **kwargs) - else: - raise + raise def _post_once(self, url, obj, content_type=JOSE_CONTENT_TYPE, acme_version=1, **kwargs): diff --git a/acme/acme/crypto_util.py b/acme/acme/crypto_util.py index 6a319d94e..66dfc738c 100644 --- a/acme/acme/crypto_util.py +++ b/acme/acme/crypto_util.py @@ -6,15 +6,15 @@ import os import re import socket -from OpenSSL import crypto -from OpenSSL import SSL # type: ignore # https://github.com/python/typeshed/issues/2052 import josepy as jose +from OpenSSL import crypto +from OpenSSL import SSL # type: ignore # https://github.com/python/typeshed/issues/2052 from acme import errors -# pylint: disable=unused-import, no-name-in-module -from acme.magic_typing import Callable, Union, Tuple, Optional -# pylint: enable=unused-import, no-name-in-module - +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 logger = logging.getLogger(__name__) @@ -28,7 +28,7 @@ logger = logging.getLogger(__name__) _DEFAULT_SSL_METHOD = SSL.SSLv23_METHOD # type: ignore -class SSLSocket(object): # pylint: disable=too-few-public-methods +class SSLSocket(object): """SSL wrapper for sockets. :ivar socket sock: Original wrapped socket. @@ -74,7 +74,7 @@ class SSLSocket(object): # pylint: disable=too-few-public-methods class FakeConnection(object): """Fake OpenSSL.SSL.Connection.""" - # pylint: disable=too-few-public-methods,missing-docstring + # pylint: disable=missing-docstring def __init__(self, connection): self._wrapped = connection diff --git a/acme/acme/errors.py b/acme/acme/errors.py index 3a0f8c596..806657940 100644 --- a/acme/acme/errors.py +++ b/acme/acme/errors.py @@ -29,7 +29,12 @@ class NonceError(ClientError): class BadNonce(NonceError): """Bad nonce error.""" def __init__(self, nonce, error, *args, **kwargs): - super(BadNonce, self).__init__(*args, **kwargs) + # MyPy complains here that there is too many arguments for BaseException constructor. + # This is an error fixed in typeshed, see https://github.com/python/mypy/issues/4183 + # The fix is included in MyPy>=0.740, but upgrading it would bring dozen of errors due to + # new types definitions. So we ignore the error until the code base is fixed to match + # with MyPy>=0.740 referential. + super(BadNonce, self).__init__(*args, **kwargs) # type: ignore self.nonce = nonce self.error = error @@ -48,7 +53,8 @@ class MissingNonce(NonceError): """ def __init__(self, response, *args, **kwargs): - super(MissingNonce, self).__init__(*args, **kwargs) + # See comment in BadNonce constructor above for an explanation of type: ignore here. + super(MissingNonce, self).__init__(*args, **kwargs) # type: ignore self.response = response def __str__(self): @@ -83,6 +89,7 @@ class PollError(ClientError): return '{0}(exhausted={1!r}, updated={2!r})'.format( self.__class__.__name__, self.exhausted, self.updated) + class ValidationError(Error): """Error for authorization failures. Contains a list of authorization resources, each of which is invalid and should have an error field. @@ -91,9 +98,11 @@ class ValidationError(Error): self.failed_authzrs = failed_authzrs super(ValidationError, self).__init__() -class TimeoutError(Error): + +class TimeoutError(Error): # pylint: disable=redefined-builtin """Error for when polling an authorization or an order times out.""" + class IssuanceError(Error): """Error sent by the server after requesting issuance of a certificate.""" @@ -105,6 +114,7 @@ class IssuanceError(Error): self.error = error super(IssuanceError, self).__init__() + class ConflictError(ClientError): """Error for when the server returns a 409 (Conflict) HTTP status. diff --git a/acme/acme/fields.py b/acme/acme/fields.py index d7ec78403..3b5672283 100644 --- a/acme/acme/fields.py +++ b/acme/acme/fields.py @@ -4,7 +4,6 @@ import logging import josepy as jose import pyrfc3339 - logger = logging.getLogger(__name__) diff --git a/acme/acme/jws.py b/acme/acme/jws.py index c92d226d4..894e69f3d 100644 --- a/acme/acme/jws.py +++ b/acme/acme/jws.py @@ -40,10 +40,10 @@ class Signature(jose.Signature): class JWS(jose.JWS): """ACME-specific JWS. Includes none, url, and kid in protected header.""" signature_cls = Signature - __slots__ = jose.JWS._orig_slots # pylint: disable=no-member + __slots__ = jose.JWS._orig_slots @classmethod - # pylint: disable=arguments-differ,too-many-arguments + # pylint: disable=arguments-differ def sign(cls, payload, key, alg, nonce, url=None, kid=None): # Per ACME spec, jwk and kid are mutually exclusive, so only include a # jwk field if kid is not provided. diff --git a/acme/acme/magic_typing.py b/acme/acme/magic_typing.py index 471b8dfa9..5a6358c69 100644 --- a/acme/acme/magic_typing.py +++ b/acme/acme/magic_typing.py @@ -1,6 +1,7 @@ """Shim class to not have to depend on typing module in prod.""" import sys + class TypingClass(object): """Ignore import errors by getting anything""" def __getattr__(self, name): diff --git a/acme/acme/messages.py b/acme/acme/messages.py index 2bfe688d2..c824c43cf 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -1,18 +1,21 @@ """ACME protocol messages.""" import json + +import josepy as jose import six + +from acme import challenges +from acme import errors +from acme import fields +from acme import jws +from acme import util + try: from collections.abc import Hashable # pylint: disable=no-name-in-module except ImportError: # pragma: no cover from collections import Hashable -import josepy as jose -from acme import challenges -from acme import errors -from acme import fields -from acme import util -from acme import jws OLD_ERROR_PREFIX = "urn:acme:error:" ERROR_PREFIX = "urn:ietf:params:acme:error:" @@ -143,7 +146,7 @@ class _Constant(jose.JSONDeSerializable, Hashable): # type: ignore if jobj not in cls.POSSIBLE_NAMES: # pylint: disable=unsupported-membership-test raise jose.DeserializationError( '{0} not recognized'.format(cls.__name__)) - return cls.POSSIBLE_NAMES[jobj] # pylint: disable=unsubscriptable-object + return cls.POSSIBLE_NAMES[jobj] def __repr__(self): return '{0}({1})'.format(self.__class__.__name__, self.name) @@ -248,7 +251,7 @@ class Directory(jose.JSONDeSerializable): 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 diff --git a/acme/acme/standalone.py b/acme/acme/standalone.py index b23b9b843..cf0da4e86 100644 --- a/acme/acme/standalone.py +++ b/acme/acme/standalone.py @@ -11,13 +11,12 @@ from six.moves import socketserver # type: ignore # pylint: disable=import-err 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 # pylint: disable=unused-import, no-name-in-module logger = logging.getLogger(__name__) # six.moves.* | pylint: disable=no-member,attribute-defined-outside-init -# pylint: disable=too-few-public-methods,no-init +# pylint: disable=no-init class TLSServer(socketserver.TCPServer): @@ -45,7 +44,7 @@ class TLSServer(socketserver.TCPServer): return socketserver.TCPServer.server_bind(self) -class ACMEServerMixin: # pylint: disable=old-style-class +class ACMEServerMixin: """ACME server common settings mixin.""" # TODO: c.f. #858 server_version = "ACME client standalone challenge solver" @@ -106,7 +105,6 @@ class BaseDualNetworkedServers(object): """Wraps socketserver.TCPServer.serve_forever""" for server in self.servers: thread = threading.Thread( - # pylint: disable=no-member target=server.serve_forever) thread.start() self.threads.append(thread) diff --git a/acme/docs/conf.py b/acme/docs/conf.py index e70651648..8c1689128 100644 --- a/acme/docs/conf.py +++ b/acme/docs/conf.py @@ -12,10 +12,9 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys import os import shlex - +import sys here = os.path.abspath(os.path.dirname(__file__)) @@ -42,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'] diff --git a/acme/examples/http01_example.py b/acme/examples/http01_example.py index 79508f1b4..2dc197d09 100644 --- a/acme/examples/http01_example.py +++ b/acme/examples/http01_example.py @@ -26,8 +26,10 @@ Workflow: - Deactivate Account """ from contextlib import contextmanager + from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import rsa +import josepy as jose import OpenSSL from acme import challenges @@ -36,7 +38,6 @@ from acme import crypto_util from acme import errors from acme import messages from acme import standalone -import josepy as jose # Constants: diff --git a/acme/readthedocs.org.requirements.txt b/acme/readthedocs.org.requirements.txt index 65e6c7cf3..168af8013 100644 --- a/acme/readthedocs.org.requirements.txt +++ b/acme/readthedocs.org.requirements.txt @@ -1,10 +1,10 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e acme[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install acme[docs]" does not work as +# expected and "pip install -e acme[docs]" must be used instead -e acme[docs] diff --git a/acme/setup.py b/acme/setup.py index 6d3dcdf84..2ab4db34e 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -1,9 +1,10 @@ -from setuptools import setup -from setuptools import find_packages -from setuptools.command.test import test as TestCommand import sys -version = '1.0.0.dev0' +from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand + +version = '1.2.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ @@ -14,8 +15,8 @@ install_requires = [ # 1.1.0+ is required to avoid the warnings described at # https://github.com/certbot/josepy/issues/13. 'josepy>=1.1.0', - # Connection.set_tlsext_host_name (>=0.13) 'mock', + # Connection.set_tlsext_host_name (>=0.13) 'PyOpenSSL>=0.13.1', 'pyrfc3339', 'pytz', diff --git a/acme/acme/challenges_test.py b/acme/tests/challenges_test.py similarity index 98% rename from acme/acme/challenges_test.py rename to acme/tests/challenges_test.py index 94641eaac..490caadc2 100644 --- a/acme/acme/challenges_test.py +++ b/acme/tests/challenges_test.py @@ -4,10 +4,9 @@ import unittest import josepy as jose import mock import requests +from six.moves.urllib import parse as urllib_parse -from six.moves.urllib import parse as urllib_parse # pylint: disable=relative-import - -from acme import test_util +import test_util CERT = test_util.load_comparable_cert('cert.pem') KEY = jose.JWKRSA(key=test_util.load_rsa_private_key('rsa512_key.pem')) @@ -19,7 +18,6 @@ class ChallengeTest(unittest.TestCase): from acme.challenges import Challenge from acme.challenges import UnrecognizedChallenge chall = UnrecognizedChallenge({"type": "foo"}) - # pylint: disable=no-member self.assertEqual(chall, Challenge.from_json(chall.jobj)) @@ -75,7 +73,6 @@ class KeyAuthorizationChallengeResponseTest(unittest.TestCase): class DNS01ResponseTest(unittest.TestCase): - # pylint: disable=too-many-instance-attributes def setUp(self): from acme.challenges import DNS01Response @@ -147,7 +144,6 @@ class DNS01Test(unittest.TestCase): class HTTP01ResponseTest(unittest.TestCase): - # pylint: disable=too-many-instance-attributes def setUp(self): from acme.challenges import HTTP01Response @@ -258,7 +254,6 @@ class HTTP01Test(unittest.TestCase): class TLSALPN01ResponseTest(unittest.TestCase): - # pylint: disable=too-many-instance-attributes def setUp(self): from acme.challenges import TLSALPN01Response diff --git a/acme/acme/client_test.py b/acme/tests/client_test.py similarity index 97% rename from acme/acme/client_test.py rename to acme/tests/client_test.py index 4c762031b..a38fedbd6 100644 --- a/acme/acme/client_test.py +++ b/acme/tests/client_test.py @@ -5,21 +5,19 @@ import datetime import json import unittest -from six.moves import http_client # pylint: disable=import-error - import josepy as jose import mock import OpenSSL import requests +from six.moves import http_client # pylint: disable=import-error from acme import challenges from acme import errors from acme import jws as acme_jws from acme import messages -from acme import messages_test -from acme import test_util -from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module - +from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module +import messages_test +import test_util CERT_DER = test_util.load_vector('cert.der') CERT_SAN_PEM = test_util.load_vector('cert-san.pem') @@ -63,7 +61,7 @@ class ClientTestBase(unittest.TestCase): self.contact = ('mailto:cert-admin@example.com', 'tel:+12025551212') reg = messages.Registration( contact=self.contact, key=KEY.public_key()) - the_arg = dict(reg) # type: Dict + the_arg = dict(reg) # type: Dict self.new_reg = messages.NewRegistration(**the_arg) self.regr = messages.RegistrationResource( body=reg, uri='https://www.letsencrypt-demo.org/acme/reg/1') @@ -318,7 +316,6 @@ class BackwardsCompatibleClientV2Test(ClientTestBase): class ClientTest(ClientTestBase): """Tests for acme.client.Client.""" - # pylint: disable=too-many-instance-attributes,too-many-public-methods def setUp(self): super(ClientTest, self).setUp() @@ -888,19 +885,6 @@ class ClientV2Test(ClientTestBase): new_nonce_url='https://www.letsencrypt-demo.org/acme/new-nonce') self.client.net.get.assert_not_called() - class FakeError(messages.Error): # pylint: disable=too-many-ancestors - """Fake error to reproduce a malformed request ACME error""" - def __init__(self): # pylint: disable=super-init-not-called - pass - @property - def code(self): - return 'malformed' - self.client.net.post.side_effect = FakeError() - - self.client.poll(self.authzr2) # pylint: disable=protected-access - - self.client.net.get.assert_called_once_with(self.authzr2.uri) - class MockJSONDeSerializable(jose.JSONDeSerializable): # pylint: disable=missing-docstring @@ -917,7 +901,6 @@ class MockJSONDeSerializable(jose.JSONDeSerializable): class ClientNetworkTest(unittest.TestCase): """Tests for acme.client.ClientNetwork.""" - # pylint: disable=too-many-public-methods def setUp(self): self.verify_ssl = mock.MagicMock() @@ -967,8 +950,8 @@ class ClientNetworkTest(unittest.TestCase): def test_check_response_not_ok_jobj_error(self): self.response.ok = False - self.response.json.return_value = messages.Error( - detail='foo', typ='serverInternal', title='some title').to_json() + self.response.json.return_value = messages.Error.with_code( + 'serverInternal', detail='foo', title='some title').to_json() # pylint: disable=protected-access self.assertRaises( messages.Error, self.net._check_response, self.response) @@ -993,7 +976,7 @@ class ClientNetworkTest(unittest.TestCase): self.response.json.side_effect = ValueError for response_ct in [self.net.JSON_CONTENT_TYPE, 'foo']: self.response.headers['Content-Type'] = response_ct - # pylint: disable=protected-access,no-value-for-parameter + # pylint: disable=protected-access self.assertEqual( self.response, self.net._check_response(self.response)) @@ -1007,7 +990,7 @@ class ClientNetworkTest(unittest.TestCase): self.response.json.return_value = {} for response_ct in [self.net.JSON_CONTENT_TYPE, 'foo']: self.response.headers['Content-Type'] = response_ct - # pylint: disable=protected-access,no-value-for-parameter + # pylint: disable=protected-access self.assertEqual( self.response, self.net._check_response(self.response)) @@ -1123,7 +1106,6 @@ class ClientNetworkTest(unittest.TestCase): class ClientNetworkWithMockedResponseTest(unittest.TestCase): """Tests for acme.client.ClientNetwork which mock out response.""" - # pylint: disable=too-many-instance-attributes def setUp(self): from acme.client import ClientNetwork @@ -1133,8 +1115,8 @@ class ClientNetworkWithMockedResponseTest(unittest.TestCase): self.response.headers = {} self.response.links = {} self.response.checked = False - self.acmev1_nonce_response = mock.MagicMock(ok=False, - status_code=http_client.METHOD_NOT_ALLOWED) + self.acmev1_nonce_response = mock.MagicMock( + ok=False, status_code=http_client.METHOD_NOT_ALLOWED) self.acmev1_nonce_response.headers = {} self.obj = mock.MagicMock() self.wrapped_obj = mock.MagicMock() diff --git a/acme/acme/crypto_util_test.py b/acme/tests/crypto_util_test.py similarity index 96% rename from acme/acme/crypto_util_test.py rename to acme/tests/crypto_util_test.py index 44b245bbe..41640ed60 100644 --- a/acme/acme/crypto_util_test.py +++ b/acme/tests/crypto_util_test.py @@ -5,15 +5,14 @@ import threading import time import unittest -import six -from six.moves import socketserver #type: ignore # pylint: disable=import-error - import josepy as jose import OpenSSL +import six +from six.moves import socketserver # type: ignore # pylint: disable=import-error from acme import errors -from acme import test_util -from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module +import test_util class SSLSocketAndProbeSNITest(unittest.TestCase): @@ -30,7 +29,6 @@ class SSLSocketAndProbeSNITest(unittest.TestCase): class _TestServer(socketserver.TCPServer): - # pylint: disable=too-few-public-methods # six.moves.* | pylint: disable=attribute-defined-outside-init,no-init def server_bind(self): # pylint: disable=missing-docstring @@ -40,7 +38,6 @@ class SSLSocketAndProbeSNITest(unittest.TestCase): self.server = _TestServer(('', 0), socketserver.BaseRequestHandler) self.port = self.server.socket.getsockname()[1] self.server_thread = threading.Thread( - # pylint: disable=no-member target=self.server.handle_request) def tearDown(self): @@ -67,7 +64,7 @@ class SSLSocketAndProbeSNITest(unittest.TestCase): def test_probe_connection_error(self): # pylint has a hard time with six - self.server.server_close() # pylint: disable=no-member + self.server.server_close() original_timeout = socket.getdefaulttimeout() try: socket.setdefaulttimeout(1) diff --git a/acme/acme/errors_test.py b/acme/tests/errors_test.py similarity index 100% rename from acme/acme/errors_test.py rename to acme/tests/errors_test.py diff --git a/acme/acme/fields_test.py b/acme/tests/fields_test.py similarity index 100% rename from acme/acme/fields_test.py rename to acme/tests/fields_test.py diff --git a/acme/acme/jose_test.py b/acme/tests/jose_test.py similarity index 87% rename from acme/acme/jose_test.py rename to acme/tests/jose_test.py index 340624a4f..e008cb6fc 100644 --- a/acme/acme/jose_test.py +++ b/acme/tests/jose_test.py @@ -2,6 +2,7 @@ import importlib import unittest + class JoseTest(unittest.TestCase): """Tests for acme.jose shim.""" @@ -20,11 +21,10 @@ class JoseTest(unittest.TestCase): # We use the imports below with eval, but pylint doesn't # understand that. - # pylint: disable=eval-used,unused-variable - import acme - import josepy - acme_jose_mod = eval(acme_jose_path) - josepy_mod = eval(josepy_path) + import acme # pylint: disable=unused-import + import josepy # pylint: disable=unused-import + acme_jose_mod = eval(acme_jose_path) # pylint: disable=eval-used + josepy_mod = eval(josepy_path) # pylint: disable=eval-used self.assertIs(acme_jose_mod, josepy_mod) self.assertIs(getattr(acme_jose_mod, attribute), getattr(josepy_mod, attribute)) diff --git a/acme/acme/jws_test.py b/acme/tests/jws_test.py similarity index 98% rename from acme/acme/jws_test.py rename to acme/tests/jws_test.py index aa3ccb700..2e6ad72dd 100644 --- a/acme/acme/jws_test.py +++ b/acme/tests/jws_test.py @@ -3,8 +3,7 @@ import unittest import josepy as jose -from acme import test_util - +import test_util KEY = jose.JWKRSA.load(test_util.load_vector('rsa512_key.pem')) diff --git a/acme/acme/magic_typing_test.py b/acme/tests/magic_typing_test.py similarity index 100% rename from acme/acme/magic_typing_test.py rename to acme/tests/magic_typing_test.py diff --git a/acme/acme/messages_test.py b/acme/tests/messages_test.py similarity index 95% rename from acme/acme/messages_test.py rename to acme/tests/messages_test.py index 7efaaa1a3..b9b70266b 100644 --- a/acme/acme/messages_test.py +++ b/acme/tests/messages_test.py @@ -5,9 +5,8 @@ import josepy as jose import mock from acme import challenges -from acme import test_util -from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module - +from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module +import test_util CERT = test_util.load_comparable_cert('cert.der') CSR = test_util.load_comparable_csr('csr.der') @@ -19,8 +18,7 @@ class ErrorTest(unittest.TestCase): def setUp(self): from acme.messages import Error, ERROR_PREFIX - self.error = Error( - detail='foo', typ=ERROR_PREFIX + 'malformed', title='title') + self.error = Error.with_code('malformed', detail='foo', title='title') self.jobj = { 'detail': 'foo', 'title': 'some title', @@ -28,7 +26,6 @@ class ErrorTest(unittest.TestCase): } self.error_custom = Error(typ='custom', detail='bar') self.empty_error = Error() - self.jobj_custom = {'type': 'custom', 'detail': 'bar'} def test_default_typ(self): from acme.messages import Error @@ -43,8 +40,7 @@ class ErrorTest(unittest.TestCase): hash(Error.from_json(self.error.to_json())) def test_description(self): - self.assertEqual( - 'The request message was malformed', self.error.description) + self.assertEqual('The request message was malformed', self.error.description) self.assertTrue(self.error_custom.description is None) def test_code(self): @@ -54,17 +50,17 @@ class ErrorTest(unittest.TestCase): self.assertEqual(None, Error().code) def test_is_acme_error(self): - from acme.messages import is_acme_error + from acme.messages import is_acme_error, Error self.assertTrue(is_acme_error(self.error)) self.assertFalse(is_acme_error(self.error_custom)) + self.assertFalse(is_acme_error(Error())) self.assertFalse(is_acme_error(self.empty_error)) self.assertFalse(is_acme_error("must pet all the {dogs|rabbits}")) def test_unicode_error(self): - from acme.messages import Error, ERROR_PREFIX, is_acme_error - arabic_error = Error( - detail=u'\u0639\u062f\u0627\u0644\u0629', typ=ERROR_PREFIX + 'malformed', - title='title') + from acme.messages import Error, is_acme_error + arabic_error = Error.with_code( + 'malformed', detail=u'\u0639\u062f\u0627\u0644\u0629', title='title') self.assertTrue(is_acme_error(arabic_error)) def test_with_code(self): @@ -305,8 +301,7 @@ class ChallengeBodyTest(unittest.TestCase): from acme.messages import Error from acme.messages import STATUS_INVALID self.status = STATUS_INVALID - error = Error(typ='urn:ietf:params:acme:error:serverInternal', - detail='Unable to communicate with DNS server') + error = Error.with_code('serverInternal', detail='Unable to communicate with DNS server') self.challb = ChallengeBody( uri='http://challb', chall=self.chall, status=self.status, error=error) diff --git a/acme/acme/standalone_test.py b/acme/tests/standalone_test.py similarity index 98% rename from acme/acme/standalone_test.py rename to acme/tests/standalone_test.py index 9f9249b07..83ced12b0 100644 --- a/acme/acme/standalone_test.py +++ b/acme/tests/standalone_test.py @@ -3,16 +3,15 @@ import socket import threading import unittest -from six.moves import http_client # pylint: disable=import-error -from six.moves import socketserver # type: ignore # pylint: disable=import-error - import josepy as jose import mock import requests +from six.moves import http_client # pylint: disable=import-error +from six.moves import socketserver # type: ignore # pylint: disable=import-error from acme import challenges -from acme import test_util -from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module +import test_util class TLSServerTest(unittest.TestCase): diff --git a/acme/acme/test_util.py b/acme/tests/test_util.py similarity index 94% rename from acme/acme/test_util.py rename to acme/tests/test_util.py index 6737bff4e..d4a45272d 100644 --- a/acme/acme/test_util.py +++ b/acme/tests/test_util.py @@ -4,12 +4,12 @@ """ import os -import pkg_resources from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization import josepy as jose from OpenSSL import crypto +import pkg_resources def load_vector(*names): @@ -25,8 +25,7 @@ def _guess_loader(filename, loader_pem, loader_der): return loader_pem elif ext.lower() == '.der': return loader_der - else: # pragma: no cover - raise ValueError("Loader could not be recognized based on extension") + raise ValueError("Loader could not be recognized based on extension") # pragma: no cover def load_cert(*names): diff --git a/acme/acme/testdata/README b/acme/tests/testdata/README similarity index 100% rename from acme/acme/testdata/README rename to acme/tests/testdata/README diff --git a/acme/acme/testdata/cert-100sans.pem b/acme/tests/testdata/cert-100sans.pem similarity index 100% rename from acme/acme/testdata/cert-100sans.pem rename to acme/tests/testdata/cert-100sans.pem diff --git a/acme/acme/testdata/cert-idnsans.pem b/acme/tests/testdata/cert-idnsans.pem similarity index 100% rename from acme/acme/testdata/cert-idnsans.pem rename to acme/tests/testdata/cert-idnsans.pem diff --git a/acme/acme/testdata/cert-nocn.der b/acme/tests/testdata/cert-nocn.der similarity index 100% rename from acme/acme/testdata/cert-nocn.der rename to acme/tests/testdata/cert-nocn.der diff --git a/acme/acme/testdata/cert-san.pem b/acme/tests/testdata/cert-san.pem similarity index 100% rename from acme/acme/testdata/cert-san.pem rename to acme/tests/testdata/cert-san.pem diff --git a/acme/acme/testdata/cert.der b/acme/tests/testdata/cert.der similarity index 100% rename from acme/acme/testdata/cert.der rename to acme/tests/testdata/cert.der diff --git a/acme/acme/testdata/cert.pem b/acme/tests/testdata/cert.pem similarity index 100% rename from acme/acme/testdata/cert.pem rename to acme/tests/testdata/cert.pem diff --git a/acme/acme/testdata/critical-san.pem b/acme/tests/testdata/critical-san.pem similarity index 100% rename from acme/acme/testdata/critical-san.pem rename to acme/tests/testdata/critical-san.pem diff --git a/acme/acme/testdata/csr-100sans.pem b/acme/tests/testdata/csr-100sans.pem similarity index 100% rename from acme/acme/testdata/csr-100sans.pem rename to acme/tests/testdata/csr-100sans.pem diff --git a/acme/acme/testdata/csr-6sans.pem b/acme/tests/testdata/csr-6sans.pem similarity index 100% rename from acme/acme/testdata/csr-6sans.pem rename to acme/tests/testdata/csr-6sans.pem diff --git a/acme/acme/testdata/csr-idnsans.pem b/acme/tests/testdata/csr-idnsans.pem similarity index 100% rename from acme/acme/testdata/csr-idnsans.pem rename to acme/tests/testdata/csr-idnsans.pem diff --git a/acme/acme/testdata/csr-nosans.pem b/acme/tests/testdata/csr-nosans.pem similarity index 100% rename from acme/acme/testdata/csr-nosans.pem rename to acme/tests/testdata/csr-nosans.pem diff --git a/acme/acme/testdata/csr-san.pem b/acme/tests/testdata/csr-san.pem similarity index 100% rename from acme/acme/testdata/csr-san.pem rename to acme/tests/testdata/csr-san.pem diff --git a/acme/acme/testdata/csr.der b/acme/tests/testdata/csr.der similarity index 100% rename from acme/acme/testdata/csr.der rename to acme/tests/testdata/csr.der diff --git a/acme/acme/testdata/csr.pem b/acme/tests/testdata/csr.pem similarity index 100% rename from acme/acme/testdata/csr.pem rename to acme/tests/testdata/csr.pem diff --git a/acme/acme/testdata/dsa512_key.pem b/acme/tests/testdata/dsa512_key.pem similarity index 100% rename from acme/acme/testdata/dsa512_key.pem rename to acme/tests/testdata/dsa512_key.pem diff --git a/acme/acme/testdata/rsa1024_key.pem b/acme/tests/testdata/rsa1024_key.pem similarity index 100% rename from acme/acme/testdata/rsa1024_key.pem rename to acme/tests/testdata/rsa1024_key.pem diff --git a/acme/acme/testdata/rsa2048_cert.pem b/acme/tests/testdata/rsa2048_cert.pem similarity index 100% rename from acme/acme/testdata/rsa2048_cert.pem rename to acme/tests/testdata/rsa2048_cert.pem diff --git a/acme/acme/testdata/rsa2048_key.pem b/acme/tests/testdata/rsa2048_key.pem similarity index 100% rename from acme/acme/testdata/rsa2048_key.pem rename to acme/tests/testdata/rsa2048_key.pem diff --git a/acme/acme/testdata/rsa256_key.pem b/acme/tests/testdata/rsa256_key.pem similarity index 100% rename from acme/acme/testdata/rsa256_key.pem rename to acme/tests/testdata/rsa256_key.pem diff --git a/acme/acme/testdata/rsa512_key.pem b/acme/tests/testdata/rsa512_key.pem similarity index 100% rename from acme/acme/testdata/rsa512_key.pem rename to acme/tests/testdata/rsa512_key.pem diff --git a/acme/acme/util_test.py b/acme/tests/util_test.py similarity index 100% rename from acme/acme/util_test.py rename to acme/tests/util_test.py diff --git a/certbot-apache/MANIFEST.in b/certbot-apache/MANIFEST.in index 3e594a953..fa15504e7 100644 --- a/certbot-apache/MANIFEST.in +++ b/certbot-apache/MANIFEST.in @@ -1,7 +1,8 @@ include LICENSE.txt include README.rst -recursive-include docs * -recursive-include certbot_apache/tests/testdata * -include certbot_apache/centos-options-ssl-apache.conf -include certbot_apache/options-ssl-apache.conf -recursive-include certbot_apache/augeas_lens *.aug +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__ +global-exclude *.py[cod] diff --git a/certbot-apache/certbot_apache/_internal/__init__.py b/certbot-apache/certbot_apache/_internal/__init__.py new file mode 100644 index 000000000..9c195ccc7 --- /dev/null +++ b/certbot-apache/certbot_apache/_internal/__init__.py @@ -0,0 +1 @@ +"""Certbot Apache plugin.""" diff --git a/certbot-apache/certbot_apache/apache_util.py b/certbot-apache/certbot_apache/_internal/apache_util.py similarity index 100% rename from certbot-apache/certbot_apache/apache_util.py rename to certbot-apache/certbot_apache/_internal/apache_util.py diff --git a/certbot-apache/certbot_apache/augeas_lens/README b/certbot-apache/certbot_apache/_internal/augeas_lens/README similarity index 100% rename from certbot-apache/certbot_apache/augeas_lens/README rename to certbot-apache/certbot_apache/_internal/augeas_lens/README diff --git a/certbot-apache/certbot_apache/augeas_lens/httpd.aug b/certbot-apache/certbot_apache/_internal/augeas_lens/httpd.aug similarity index 100% rename from certbot-apache/certbot_apache/augeas_lens/httpd.aug rename to certbot-apache/certbot_apache/_internal/augeas_lens/httpd.aug diff --git a/certbot-apache/certbot_apache/centos-options-ssl-apache.conf b/certbot-apache/certbot_apache/_internal/centos-options-ssl-apache.conf similarity index 100% rename from certbot-apache/certbot_apache/centos-options-ssl-apache.conf rename to certbot-apache/certbot_apache/_internal/centos-options-ssl-apache.conf diff --git a/certbot-apache/certbot_apache/configurator.py b/certbot-apache/certbot_apache/_internal/configurator.py similarity index 96% rename from certbot-apache/certbot_apache/configurator.py rename to certbot-apache/certbot_apache/_internal/configurator.py index 57cd4a9b4..20c225e04 100644 --- a/certbot-apache/certbot_apache/configurator.py +++ b/certbot-apache/certbot_apache/_internal/configurator.py @@ -1,5 +1,6 @@ """Apache Configurator.""" # pylint: disable=too-many-lines +from collections import defaultdict import copy import fnmatch import logging @@ -7,34 +8,32 @@ import re import socket import time -from collections import defaultdict - import pkg_resources import six - import zope.component import zope.interface from acme import challenges -from acme.magic_typing import DefaultDict, Dict, List, Set, Union # pylint: disable=unused-import, no-name-in-module - +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 certbot import errors from certbot import interfaces from certbot import util - from certbot.achallenges import KeyAuthorizationAnnotatedChallenge # pylint: disable=unused-import from certbot.compat import filesystem from certbot.compat import os from certbot.plugins import common -from certbot.plugins.util import path_surgery from certbot.plugins.enhancements import AutoHSTSEnhancement - -from certbot_apache import apache_util -from certbot_apache import constants -from certbot_apache import display_ops -from certbot_apache import http_01 -from certbot_apache import obj -from certbot_apache import parser +from certbot.plugins.util import path_surgery +from certbot_apache._internal import apache_util +from certbot_apache._internal import constants +from certbot_apache._internal import display_ops +from certbot_apache._internal import http_01 +from certbot_apache._internal import obj +from certbot_apache._internal import parser logger = logging.getLogger(__name__) @@ -71,18 +70,17 @@ logger = logging.getLogger(__name__) @zope.interface.implementer(interfaces.IAuthenticator, interfaces.IInstaller) @zope.interface.provider(interfaces.IPluginFactory) class ApacheConfigurator(common.Installer): - # pylint: disable=too-many-instance-attributes,too-many-public-methods """Apache configurator. :ivar config: Configuration. :type config: :class:`~certbot.interfaces.IConfig` :ivar parser: Handles low level parsing - :type parser: :class:`~certbot_apache.parser` + :type parser: :class:`~certbot_apache._internal.parser` :ivar tup version: version of Apache :ivar list vhosts: All vhosts found in the configuration - (:class:`list` of :class:`~certbot_apache.obj.VirtualHost`) + (:class:`list` of :class:`~certbot_apache._internal.obj.VirtualHost`) :ivar dict assoc: Mapping between domains and vhosts @@ -111,7 +109,7 @@ class ApacheConfigurator(common.Installer): handle_sites=False, challenge_location="/etc/apache2", MOD_SSL_CONF_SRC=pkg_resources.resource_filename( - "certbot_apache", "options-ssl-apache.conf") + "certbot_apache", os.path.join("_internal", "options-ssl-apache.conf")) ) def option(self, key): @@ -392,7 +390,7 @@ class ApacheConfigurator(common.Installer): counterpart, should one get created :returns: List of VirtualHosts or None - :rtype: `list` of :class:`~certbot_apache.obj.VirtualHost` + :rtype: `list` of :class:`~certbot_apache._internal.obj.VirtualHost` """ if self._wildcard_domain(domain): @@ -451,7 +449,7 @@ class ApacheConfigurator(common.Installer): filtered_vhosts[name] = vhost # Only unique VHost objects - dialog_input = set([vhost for vhost in filtered_vhosts.values()]) + dialog_input = set(filtered_vhosts.values()) # Ask the user which of names to enable, expect list of names back dialog_output = display_ops.select_vhost_multiple(list(dialog_input)) @@ -567,7 +565,7 @@ class ApacheConfigurator(common.Installer): counterpart, should one get created :returns: vhost associated with name - :rtype: :class:`~certbot_apache.obj.VirtualHost` + :rtype: :class:`~certbot_apache._internal.obj.VirtualHost` :raises .errors.PluginError: If no vhost is available or chosen @@ -602,9 +600,9 @@ class ApacheConfigurator(common.Installer): "in the Apache config.", target_name) raise errors.PluginError("No vhost selected") - elif temp: + if temp: return vhost - elif not vhost.ssl: + if not vhost.ssl: addrs = self._get_proposed_addrs(vhost, "443") # TODO: Conflicts is too conservative if not any(vhost.enabled and vhost.conflicts(addrs) for @@ -670,7 +668,7 @@ class ApacheConfigurator(common.Installer): :param str target_name: domain handled by the desired vhost :param vhosts: vhosts to consider - :type vhosts: `collections.Iterable` of :class:`~certbot_apache.obj.VirtualHost` + :type vhosts: `collections.Iterable` of :class:`~certbot_apache._internal.obj.VirtualHost` :param bool filter_defaults: whether a vhost with a _default_ addr is acceptable @@ -812,7 +810,7 @@ class ApacheConfigurator(common.Installer): """Helper function for get_virtual_hosts(). :param host: In progress vhost whose names will be added - :type host: :class:`~certbot_apache.obj.VirtualHost` + :type host: :class:`~certbot_apache._internal.obj.VirtualHost` """ @@ -831,7 +829,7 @@ class ApacheConfigurator(common.Installer): :param str path: Augeas path to virtual host :returns: newly created vhost - :rtype: :class:`~certbot_apache.obj.VirtualHost` + :rtype: :class:`~certbot_apache._internal.obj.VirtualHost` """ addrs = set() @@ -872,7 +870,7 @@ class ApacheConfigurator(common.Installer): def get_virtual_hosts(self): """Returns list of virtual hosts found in the Apache configuration. - :returns: List of :class:`~certbot_apache.obj.VirtualHost` + :returns: List of :class:`~certbot_apache._internal.obj.VirtualHost` objects found in configuration :rtype: list @@ -929,7 +927,7 @@ class ApacheConfigurator(common.Installer): now NameVirtualHosts. If version is earlier than 2.4, check if addr has a NameVirtualHost directive in the Apache config - :param certbot_apache.obj.Addr target_addr: vhost address + :param certbot_apache._internal.obj.Addr target_addr: vhost address :returns: Success :rtype: bool @@ -947,19 +945,18 @@ class ApacheConfigurator(common.Installer): """Adds NameVirtualHost directive for given address. :param addr: Address that will be added as NameVirtualHost directive - :type addr: :class:`~certbot_apache.obj.Addr` + :type addr: :class:`~certbot_apache._internal.obj.Addr` """ loc = parser.get_aug_path(self.parser.loc["name"]) if addr.get_port() == "443": - path = self.parser.add_dir_to_ifmodssl( + self.parser.add_dir_to_ifmodssl( loc, "NameVirtualHost", [str(addr)]) else: - path = self.parser.add_dir(loc, "NameVirtualHost", [str(addr)]) + self.parser.add_dir(loc, "NameVirtualHost", [str(addr)]) - msg = ("Setting %s to be NameBasedVirtualHost\n" - "\tDirective added to %s\n" % (addr, path)) + msg = "Setting {0} to be NameBasedVirtualHost\n".format(addr) logger.debug(msg) self.save_notes += msg @@ -1116,7 +1113,7 @@ class ApacheConfigurator(common.Installer): if "ssl_module" not in self.parser.modules: self.enable_mod("ssl", temp=temp) - def make_vhost_ssl(self, nonssl_vhost): # pylint: disable=too-many-locals + def make_vhost_ssl(self, nonssl_vhost): """Makes an ssl_vhost version of a nonssl_vhost. Duplicates vhost and adds default ssl options @@ -1126,10 +1123,10 @@ class ApacheConfigurator(common.Installer): .. note:: This function saves the configuration :param nonssl_vhost: Valid VH that doesn't have SSLEngine on - :type nonssl_vhost: :class:`~certbot_apache.obj.VirtualHost` + :type nonssl_vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :returns: SSL vhost - :rtype: :class:`~certbot_apache.obj.VirtualHost` + :rtype: :class:`~certbot_apache._internal.obj.VirtualHost` :raises .errors.PluginError: If more than one virtual host is in the file or if plugin is unable to write/read vhost files. @@ -1367,12 +1364,9 @@ class ApacheConfigurator(common.Installer): result.append(comment) sift = True - result.append('\n'.join( - ['# ' + l for l in chunk])) - continue + result.append('\n'.join(['# ' + l for l in chunk])) else: result.append('\n'.join(chunk)) - continue return result, sift def _get_vhost_block(self, vhost): @@ -1500,7 +1494,7 @@ class ApacheConfigurator(common.Installer): https://httpd.apache.org/docs/2.2/mod/core.html#namevirtualhost :param vhost: New virtual host that was recently created. - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` """ need_to_save = False @@ -1535,7 +1529,7 @@ class ApacheConfigurator(common.Installer): :param str id_str: Id string for matching :returns: The matched VirtualHost or None - :rtype: :class:`~certbot_apache.obj.VirtualHost` or None + :rtype: :class:`~certbot_apache._internal.obj.VirtualHost` or None :raises .errors.PluginError: If no VirtualHost is found """ @@ -1552,7 +1546,7 @@ class ApacheConfigurator(common.Installer): used for keeping track of VirtualHost directive over time. :param vhost: Virtual host to add the id - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :returns: The unique ID or None :rtype: str or None @@ -1574,7 +1568,7 @@ class ApacheConfigurator(common.Installer): If ID already exists, returns that instead. :param vhost: Virtual host to add or find the id - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :returns: The unique ID for vhost :rtype: str or None @@ -1652,7 +1646,7 @@ class ApacheConfigurator(common.Installer): """Increase the AutoHSTS max-age value :param vhost: Virtual host object to modify - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :param str id_str: The unique ID string of VirtualHost @@ -1736,13 +1730,13 @@ class ApacheConfigurator(common.Installer): .. note:: This function saves the configuration :param ssl_vhost: Destination of traffic, an ssl enabled vhost - :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost` + :type ssl_vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :param unused_options: Not currently used :type unused_options: Not Available :returns: Success, general_vhost (HTTP vhost) - :rtype: (bool, :class:`~certbot_apache.obj.VirtualHost`) + :rtype: (bool, :class:`~certbot_apache._internal.obj.VirtualHost`) """ min_apache_ver = (2, 3, 3) @@ -1792,14 +1786,14 @@ class ApacheConfigurator(common.Installer): .. note:: This function saves the configuration :param ssl_vhost: Destination of traffic, an ssl enabled vhost - :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost` + :type ssl_vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :param header_substring: string that uniquely identifies a header. e.g: Strict-Transport-Security, Upgrade-Insecure-Requests. :type str :returns: Success, general_vhost (HTTP vhost) - :rtype: (bool, :class:`~certbot_apache.obj.VirtualHost`) + :rtype: (bool, :class:`~certbot_apache._internal.obj.VirtualHost`) :raises .errors.PluginError: If no viable HTTP host can be created or set with header header_substring. @@ -1827,7 +1821,7 @@ class ApacheConfigurator(common.Installer): contains the string header_substring. :param ssl_vhost: vhost to check - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :param header_substring: string that uniquely identifies a header. e.g: Strict-Transport-Security, Upgrade-Insecure-Requests. @@ -1864,7 +1858,7 @@ class ApacheConfigurator(common.Installer): .. note:: This function saves the configuration :param ssl_vhost: Destination of traffic, an ssl enabled vhost - :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost` + :type ssl_vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :param unused_options: Not currently used :type unused_options: Not Available @@ -1949,7 +1943,7 @@ class ApacheConfigurator(common.Installer): delete certbot's old rewrite rules and set the new one instead. :param vhost: vhost to check - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :raises errors.PluginEnhancementAlreadyPresent: When the exact certbot redirection WriteRule exists in virtual host. @@ -1991,7 +1985,7 @@ class ApacheConfigurator(common.Installer): """Checks if there exists a RewriteRule directive in vhost :param vhost: vhost to check - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :returns: True if a RewriteRule directive exists. :rtype: bool @@ -2005,7 +1999,7 @@ class ApacheConfigurator(common.Installer): """Checks if a RewriteEngine directive is on :param vhost: vhost to check - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` """ rewrite_engine_path_list = self.parser.find_dir("RewriteEngine", "on", @@ -2022,10 +2016,10 @@ class ApacheConfigurator(common.Installer): """Creates an http_vhost specifically to redirect for the ssl_vhost. :param ssl_vhost: ssl vhost - :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost` + :type ssl_vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :returns: tuple of the form - (`success`, :class:`~certbot_apache.obj.VirtualHost`) + (`success`, :class:`~certbot_apache._internal.obj.VirtualHost`) :rtype: tuple """ @@ -2151,7 +2145,7 @@ class ApacheConfigurator(common.Installer): of this method where available. :param vhost: vhost to enable - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :raises .errors.NotSupportedError: If filesystem layout is not supported. @@ -2388,7 +2382,7 @@ class ApacheConfigurator(common.Installer): """Do the initial AutoHSTS deployment to a vhost :param ssl_vhost: The VirtualHost object to deploy the AutoHSTS - :type ssl_vhost: :class:`~certbot_apache.obj.VirtualHost` or None + :type ssl_vhost: :class:`~certbot_apache._internal.obj.VirtualHost` or None :raises errors.PluginEnhancementAlreadyPresent: When already enhanced @@ -2515,4 +2509,4 @@ class ApacheConfigurator(common.Installer): self._autohsts_save_state() -AutoHSTSEnhancement.register(ApacheConfigurator) # pylint: disable=no-member +AutoHSTSEnhancement.register(ApacheConfigurator) diff --git a/certbot-apache/certbot_apache/constants.py b/certbot-apache/certbot_apache/_internal/constants.py similarity index 96% rename from certbot-apache/certbot_apache/constants.py rename to certbot-apache/certbot_apache/_internal/constants.py index f8184a42f..47e3be856 100644 --- a/certbot-apache/certbot_apache/constants.py +++ b/certbot-apache/certbot_apache/_internal/constants.py @@ -1,6 +1,7 @@ """Apache plugin constants.""" import pkg_resources +from certbot.compat import os MOD_SSL_CONF_DEST = "options-ssl-apache.conf" """Name of the mod_ssl config file as saved in `IConfig.config_dir`.""" @@ -27,7 +28,7 @@ ALL_SSL_OPTIONS_HASHES = [ """SHA256 hashes of the contents of previous versions of all versions of MOD_SSL_CONF_SRC""" AUGEAS_LENS_DIR = pkg_resources.resource_filename( - "certbot_apache", "augeas_lens") + "certbot_apache", os.path.join("_internal", "augeas_lens")) """Path to the Augeas lens directory""" REWRITE_HTTPS_ARGS = [ diff --git a/certbot-apache/certbot_apache/display_ops.py b/certbot-apache/certbot_apache/_internal/display_ops.py similarity index 98% rename from certbot-apache/certbot_apache/display_ops.py rename to certbot-apache/certbot_apache/_internal/display_ops.py index 2639eabd1..1ae32bb47 100644 --- a/certbot-apache/certbot_apache/display_ops.py +++ b/certbot-apache/certbot_apache/_internal/display_ops.py @@ -3,10 +3,10 @@ import logging import zope.component -import certbot.display.util as display_util from certbot import errors from certbot import interfaces from certbot.compat import os +import certbot.display.util as display_util logger = logging.getLogger(__name__) @@ -77,7 +77,7 @@ def _vhost_menu(domain, vhosts): if free_chars < 2: logger.debug("Display size is too small for " - "certbot_apache.display_ops._vhost_menu()") + "certbot_apache._internal.display_ops._vhost_menu()") # This runs the edge off the screen, but it doesn't cause an "error" filename_size = 1 disp_name_size = 1 diff --git a/certbot-apache/certbot_apache/entrypoint.py b/certbot-apache/certbot_apache/_internal/entrypoint.py similarity index 85% rename from certbot-apache/certbot_apache/entrypoint.py rename to certbot-apache/certbot_apache/_internal/entrypoint.py index 9e04ff889..d43094976 100644 --- a/certbot-apache/certbot_apache/entrypoint.py +++ b/certbot-apache/certbot_apache/_internal/entrypoint.py @@ -4,15 +4,14 @@ from distutils.version import LooseVersion # pylint: disable=no-name-in-module,import-error from certbot import util - -from certbot_apache import configurator -from certbot_apache import override_arch -from certbot_apache import override_fedora -from certbot_apache import override_darwin -from certbot_apache import override_debian -from certbot_apache import override_centos -from certbot_apache import override_gentoo -from certbot_apache import override_suse +from certbot_apache._internal import configurator +from certbot_apache._internal import override_arch +from certbot_apache._internal import override_centos +from certbot_apache._internal import override_darwin +from certbot_apache._internal import override_debian +from certbot_apache._internal import override_fedora +from certbot_apache._internal import override_gentoo +from certbot_apache._internal import override_suse OVERRIDE_CLASSES = { "arch": override_arch.ArchConfigurator, diff --git a/certbot-apache/certbot_apache/http_01.py b/certbot-apache/certbot_apache/_internal/http_01.py similarity index 95% rename from certbot-apache/certbot_apache/http_01.py rename to certbot-apache/certbot_apache/_internal/http_01.py index de22edd85..c34abc2b4 100644 --- a/certbot-apache/certbot_apache/http_01.py +++ b/certbot-apache/certbot_apache/_internal/http_01.py @@ -1,15 +1,14 @@ """A class that performs HTTP-01 challenges for Apache""" import logging -from acme.magic_typing import List, Set # 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 certbot import errors -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os from certbot.plugins import common - -from certbot_apache.obj import VirtualHost # pylint: disable=unused-import -from certbot_apache.parser import get_aug_path +from certbot_apache._internal.obj import VirtualHost # pylint: disable=unused-import +from certbot_apache._internal.parser import get_aug_path logger = logging.getLogger(__name__) @@ -195,8 +194,8 @@ class ApacheHttp01(common.ChallengePerformer): if vhost not in self.moded_vhosts: logger.debug( - "Adding a temporary challenge validation Include for name: %s " + - "in: %s", vhost.name, vhost.filep) + "Adding a temporary challenge validation Include for name: %s in: %s", + vhost.name, vhost.filep) self.configurator.parser.add_dir_beginning( vhost.path, "Include", self.challenge_conf_pre) self.configurator.parser.add_dir( diff --git a/certbot-apache/certbot_apache/obj.py b/certbot-apache/certbot_apache/_internal/obj.py similarity index 97% rename from certbot-apache/certbot_apache/obj.py rename to certbot-apache/certbot_apache/_internal/obj.py index 22abc85cd..8b3aeb376 100644 --- a/certbot-apache/certbot_apache/obj.py +++ b/certbot-apache/certbot_apache/_internal/obj.py @@ -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 # pylint: disable=unused-import, no-name-in-module from certbot.plugins import common @@ -24,7 +24,7 @@ class Addr(common.Addr): return not self.__eq__(other) def __repr__(self): - return "certbot_apache.obj.Addr(" + repr(self.tup) + ")" + return "certbot_apache._internal.obj.Addr(" + repr(self.tup) + ")" def __hash__(self): # pylint: disable=useless-super-delegation # Python 3 requires explicit overridden for __hash__ if __eq__ or @@ -98,7 +98,7 @@ class Addr(common.Addr): return self.get_addr_obj(port) -class VirtualHost(object): # pylint: disable=too-few-public-methods +class VirtualHost(object): """Represents an Apache Virtualhost. :ivar str filep: file path of VH @@ -126,7 +126,6 @@ class VirtualHost(object): # pylint: disable=too-few-public-methods def __init__(self, filep, path, addrs, ssl, enabled, name=None, aliases=None, modmacro=False, ancestor=None): - # pylint: disable=too-many-arguments """Initialize a VH.""" self.filep = filep self.path = path diff --git a/certbot-apache/certbot_apache/options-ssl-apache.conf b/certbot-apache/certbot_apache/_internal/options-ssl-apache.conf similarity index 100% rename from certbot-apache/certbot_apache/options-ssl-apache.conf rename to certbot-apache/certbot_apache/_internal/options-ssl-apache.conf diff --git a/certbot-apache/certbot_apache/override_arch.py b/certbot-apache/certbot_apache/_internal/override_arch.py similarity index 84% rename from certbot-apache/certbot_apache/override_arch.py rename to certbot-apache/certbot_apache/_internal/override_arch.py index c5620e9f9..2765bd238 100644 --- a/certbot-apache/certbot_apache/override_arch.py +++ b/certbot-apache/certbot_apache/_internal/override_arch.py @@ -1,11 +1,11 @@ """ Distribution specific override class for Arch Linux """ import pkg_resources - import zope.interface from certbot import interfaces +from certbot.compat import os +from certbot_apache._internal import configurator -from certbot_apache import configurator @zope.interface.provider(interfaces.IPluginFactory) class ArchConfigurator(configurator.ApacheConfigurator): @@ -27,5 +27,5 @@ class ArchConfigurator(configurator.ApacheConfigurator): handle_sites=False, challenge_location="/etc/httpd/conf", MOD_SSL_CONF_SRC=pkg_resources.resource_filename( - "certbot_apache", "options-ssl-apache.conf") + "certbot_apache", os.path.join("_internal", "options-ssl-apache.conf")) ) diff --git a/certbot-apache/certbot_apache/override_centos.py b/certbot-apache/certbot_apache/_internal/override_centos.py similarity index 96% rename from certbot-apache/certbot_apache/override_centos.py rename to certbot-apache/certbot_apache/_internal/override_centos.py index 7c7492dbf..b3576e083 100644 --- a/certbot-apache/certbot_apache/override_centos.py +++ b/certbot-apache/certbot_apache/_internal/override_centos.py @@ -4,17 +4,15 @@ import logging import pkg_resources import zope.interface +from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module from certbot import errors from certbot import interfaces from certbot import util +from certbot.compat import os from certbot.errors import MisconfigurationError - -from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - -from certbot_apache import apache_util -from certbot_apache import configurator -from certbot_apache import parser - +from certbot_apache._internal import apache_util +from certbot_apache._internal import configurator +from certbot_apache._internal import parser logger = logging.getLogger(__name__) @@ -40,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", "centos-options-ssl-apache.conf") + "certbot_apache", os.path.join("_internal", "centos-options-ssl-apache.conf")) ) def config_test(self): diff --git a/certbot-apache/certbot_apache/override_darwin.py b/certbot-apache/certbot_apache/_internal/override_darwin.py similarity index 84% rename from certbot-apache/certbot_apache/override_darwin.py rename to certbot-apache/certbot_apache/_internal/override_darwin.py index 4e2a6acac..00faff623 100644 --- a/certbot-apache/certbot_apache/override_darwin.py +++ b/certbot-apache/certbot_apache/_internal/override_darwin.py @@ -1,11 +1,11 @@ """ Distribution specific override class for macOS """ import pkg_resources - import zope.interface from certbot import interfaces +from certbot.compat import os +from certbot_apache._internal import configurator -from certbot_apache import configurator @zope.interface.provider(interfaces.IPluginFactory) class DarwinConfigurator(configurator.ApacheConfigurator): @@ -27,5 +27,5 @@ class DarwinConfigurator(configurator.ApacheConfigurator): handle_sites=False, challenge_location="/etc/apache2/other", MOD_SSL_CONF_SRC=pkg_resources.resource_filename( - "certbot_apache", "options-ssl-apache.conf") + "certbot_apache", os.path.join("_internal", "options-ssl-apache.conf")) ) diff --git a/certbot-apache/certbot_apache/override_debian.py b/certbot-apache/certbot_apache/_internal/override_debian.py similarity index 86% rename from certbot-apache/certbot_apache/override_debian.py rename to certbot-apache/certbot_apache/_internal/override_debian.py index 58492bd01..77ced6a3f 100644 --- a/certbot-apache/certbot_apache/override_debian.py +++ b/certbot-apache/certbot_apache/_internal/override_debian.py @@ -9,9 +9,8 @@ from certbot import interfaces from certbot import util from certbot.compat import filesystem from certbot.compat import os - -from certbot_apache import apache_util -from certbot_apache import configurator +from certbot_apache._internal import apache_util +from certbot_apache._internal import configurator logger = logging.getLogger(__name__) @@ -36,7 +35,7 @@ class DebianConfigurator(configurator.ApacheConfigurator): handle_sites=True, challenge_location="/etc/apache2", MOD_SSL_CONF_SRC=pkg_resources.resource_filename( - "certbot_apache", "options-ssl-apache.conf") + "certbot_apache", os.path.join("_internal", "options-ssl-apache.conf")) ) def enable_site(self, vhost): @@ -46,7 +45,7 @@ class DebianConfigurator(configurator.ApacheConfigurator): modules are enabled appropriately. :param vhost: vhost to enable - :type vhost: :class:`~certbot_apache.obj.VirtualHost` + :type vhost: :class:`~certbot_apache._internal.obj.VirtualHost` :raises .errors.NotSupportedError: If filesystem layout is not supported. @@ -71,15 +70,14 @@ class DebianConfigurator(configurator.ApacheConfigurator): # Already in shape vhost.enabled = True return None - else: - logger.warning( - "Could not symlink %s to %s, got error: %s", enabled_path, - vhost.filep, err.strerror) - errstring = ("Encountered error while trying to enable a " + - "newly created VirtualHost located at {0} by " + - "linking to it from {1}") - raise errors.NotSupportedError(errstring.format(vhost.filep, - enabled_path)) + logger.warning( + "Could not symlink %s to %s, got error: %s", enabled_path, + vhost.filep, err.strerror) + errstring = ("Encountered error while trying to enable a " + + "newly created VirtualHost located at {0} by " + + "linking to it from {1}") + raise errors.NotSupportedError(errstring.format(vhost.filep, + enabled_path)) vhost.enabled = True logger.info("Enabling available site: %s", vhost.filep) self.save_notes += "Enabled site %s\n" % vhost.filep diff --git a/certbot-apache/certbot_apache/override_fedora.py b/certbot-apache/certbot_apache/_internal/override_fedora.py similarity index 93% rename from certbot-apache/certbot_apache/override_fedora.py rename to certbot-apache/certbot_apache/_internal/override_fedora.py index 786ada0fc..a9607a60f 100644 --- a/certbot-apache/certbot_apache/override_fedora.py +++ b/certbot-apache/certbot_apache/_internal/override_fedora.py @@ -5,10 +5,10 @@ import zope.interface from certbot import errors from certbot import interfaces from certbot import util - -from certbot_apache import apache_util -from certbot_apache import configurator -from certbot_apache import parser +from certbot.compat import os +from certbot_apache._internal import apache_util +from certbot_apache._internal import configurator +from certbot_apache._internal import parser @zope.interface.provider(interfaces.IPluginFactory) @@ -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", "centos-options-ssl-apache.conf") + "certbot_apache", os.path.join("_internal", "centos-options-ssl-apache.conf")) ) def config_test(self): diff --git a/certbot-apache/certbot_apache/override_gentoo.py b/certbot-apache/certbot_apache/_internal/override_gentoo.py similarity index 90% rename from certbot-apache/certbot_apache/override_gentoo.py rename to certbot-apache/certbot_apache/_internal/override_gentoo.py index c358a10fa..38f8aebe9 100644 --- a/certbot-apache/certbot_apache/override_gentoo.py +++ b/certbot-apache/certbot_apache/_internal/override_gentoo.py @@ -1,13 +1,13 @@ """ Distribution specific override class for Gentoo Linux """ import pkg_resources - import zope.interface from certbot import interfaces +from certbot.compat import os +from certbot_apache._internal import apache_util +from certbot_apache._internal import configurator +from certbot_apache._internal import parser -from certbot_apache import apache_util -from certbot_apache import configurator -from certbot_apache import parser @zope.interface.provider(interfaces.IPluginFactory) class GentooConfigurator(configurator.ApacheConfigurator): @@ -30,7 +30,7 @@ class GentooConfigurator(configurator.ApacheConfigurator): handle_sites=False, challenge_location="/etc/apache2/vhosts.d", MOD_SSL_CONF_SRC=pkg_resources.resource_filename( - "certbot_apache", "options-ssl-apache.conf") + "certbot_apache", os.path.join("_internal", "options-ssl-apache.conf")) ) def _prepare_options(self): diff --git a/certbot-apache/certbot_apache/override_suse.py b/certbot-apache/certbot_apache/_internal/override_suse.py similarity index 84% rename from certbot-apache/certbot_apache/override_suse.py rename to certbot-apache/certbot_apache/_internal/override_suse.py index 3d0043afe..0c9219e6d 100644 --- a/certbot-apache/certbot_apache/override_suse.py +++ b/certbot-apache/certbot_apache/_internal/override_suse.py @@ -1,11 +1,11 @@ """ Distribution specific override class for OpenSUSE """ import pkg_resources - import zope.interface from certbot import interfaces +from certbot.compat import os +from certbot_apache._internal import configurator -from certbot_apache import configurator @zope.interface.provider(interfaces.IPluginFactory) class OpenSUSEConfigurator(configurator.ApacheConfigurator): @@ -27,5 +27,5 @@ class OpenSUSEConfigurator(configurator.ApacheConfigurator): handle_sites=False, challenge_location="/etc/apache2/vhosts.d", MOD_SSL_CONF_SRC=pkg_resources.resource_filename( - "certbot_apache", "options-ssl-apache.conf") + "certbot_apache", os.path.join("_internal", "options-ssl-apache.conf")) ) diff --git a/certbot-apache/certbot_apache/parser.py b/certbot-apache/certbot_apache/_internal/parser.py similarity index 98% rename from certbot-apache/certbot_apache/parser.py rename to certbot-apache/certbot_apache/_internal/parser.py index b5f0cd81a..e4073ee16 100644 --- a/certbot-apache/certbot_apache/parser.py +++ b/certbot-apache/certbot_apache/_internal/parser.py @@ -8,18 +8,17 @@ import sys import six -from acme.magic_typing import Dict, List, Set # 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 certbot import errors from certbot.compat import os - -from certbot_apache import constants +from certbot_apache._internal import constants logger = logging.getLogger(__name__) class ApacheParser(object): - # pylint: disable=too-many-public-methods """Class handles the fine details of parsing the Apache Configuration. .. todo:: Make parsing general... remove sites-available etc... @@ -285,8 +284,8 @@ class ApacheParser(object): mods.add(mod_name) mods.add(os.path.basename(mod_filename)[:-2] + "c") else: - logger.debug("Could not read LoadModule directive from " + - "Augeas path: %s", match_name[6:]) + logger.debug("Could not read LoadModule directive from Augeas path: %s", + match_name[6:]) self.modules.update(mods) def update_runtime_variables(self): @@ -626,7 +625,7 @@ class ApacheParser(object): # https://httpd.apache.org/docs/2.4/mod/core.html#include for match in matches: dir_ = self.aug.get(match).lower() - if dir_ == "include" or dir_ == "includeoptional": + if dir_ in ("include", "includeoptional"): ordered_matches.extend(self.find_dir( directive, arg, self._get_include_path(self.get_arg(match + "/arg")), @@ -666,8 +665,7 @@ class ApacheParser(object): # e.g. strip now, not later if not value: return None - else: - value = value.strip("'\"") + value = value.strip("'\"") variables = ApacheParser.arg_var_interpreter.findall(value) diff --git a/certbot-apache/certbot_apache/tests/__init__.py b/certbot-apache/certbot_apache/tests/__init__.py deleted file mode 100644 index 7e7d39fa4..000000000 --- a/certbot-apache/certbot_apache/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Certbot Apache Tests""" diff --git a/certbot-apache/docs/Makefile b/certbot-apache/docs/Makefile deleted file mode 100644 index 0e611ecec..000000000 --- a/certbot-apache/docs/Makefile +++ /dev/null @@ -1,192 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/certbot-apache.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/certbot-apache.qhc" - -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/certbot-apache" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/certbot-apache" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/certbot-apache/docs/_templates/.gitignore b/certbot-apache/docs/_templates/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/certbot-apache/docs/api/augeas_configurator.rst b/certbot-apache/docs/api/augeas_configurator.rst deleted file mode 100644 index b47ffbc6b..000000000 --- a/certbot-apache/docs/api/augeas_configurator.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_apache.augeas_configurator` ---------------------------------------------- - -.. automodule:: certbot_apache.augeas_configurator - :members: diff --git a/certbot-apache/docs/api/configurator.rst b/certbot-apache/docs/api/configurator.rst deleted file mode 100644 index 8ec266d1a..000000000 --- a/certbot-apache/docs/api/configurator.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_apache.configurator` --------------------------------------- - -.. automodule:: certbot_apache.configurator - :members: diff --git a/certbot-apache/docs/api/display_ops.rst b/certbot-apache/docs/api/display_ops.rst deleted file mode 100644 index 26d3ed3dc..000000000 --- a/certbot-apache/docs/api/display_ops.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_apache.display_ops` -------------------------------------- - -.. automodule:: certbot_apache.display_ops - :members: diff --git a/certbot-apache/docs/api/obj.rst b/certbot-apache/docs/api/obj.rst deleted file mode 100644 index 82e58df3f..000000000 --- a/certbot-apache/docs/api/obj.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_apache.obj` ------------------------------ - -.. automodule:: certbot_apache.obj - :members: diff --git a/certbot-apache/docs/api/parser.rst b/certbot-apache/docs/api/parser.rst deleted file mode 100644 index 3427735be..000000000 --- a/certbot-apache/docs/api/parser.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_apache.parser` --------------------------------- - -.. automodule:: certbot_apache.parser - :members: diff --git a/certbot-apache/docs/conf.py b/certbot-apache/docs/conf.py deleted file mode 100644 index 5375fd2b8..000000000 --- a/certbot-apache/docs/conf.py +++ /dev/null @@ -1,318 +0,0 @@ -# -*- coding: utf-8 -*- -# -# certbot-apache documentation build configuration file, created by -# sphinx-quickstart on Sun Oct 18 13:39:26 2015. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -from certbot.compat import os -import shlex - -import mock - - -# http://docs.readthedocs.org/en/latest/faq.html#i-get-import-errors-on-libraries-that-depend-on-c-modules -# c.f. #262 -sys.modules.update( - (mod_name, mock.MagicMock()) for mod_name in ['augeas']) - -here = os.path.abspath(os.path.dirname(__file__)) - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath(os.path.join(here, '..'))) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.viewcode', -] - -autodoc_member_order = 'bysource' -autodoc_default_flags = ['show-inheritance', 'private-members'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'certbot-apache' -copyright = u'2014-2015, Let\'s Encrypt Project' -author = u'Certbot Project' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0' -# The full version, including alpha/beta/rc tags. -release = '0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = 'en' - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -default_role = 'py:obj' - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. - -# http://docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs -# on_rtd is whether we are on readthedocs.org -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' -if not on_rtd: # only import and set the theme if we're building docs locally - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -# otherwise, readthedocs.org uses their theme by default, so no need to specify it - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'certbot-apachedoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - #'preamble': '', - - # Latex figure (float) alignment - #'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'certbot-apache.tex', u'certbot-apache Documentation', - u'Certbot Project', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'certbot-apache', u'certbot-apache Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'certbot-apache', u'certbot-apache Documentation', - author, 'certbot-apache', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - - -intersphinx_mapping = { - 'python': ('https://docs.python.org/', None), - 'acme': ('https://acme-python.readthedocs.org/en/latest/', None), - 'certbot': ('https://certbot.eff.org/docs/', None), -} diff --git a/certbot-apache/docs/index.rst b/certbot-apache/docs/index.rst deleted file mode 100644 index bfe4d245c..000000000 --- a/certbot-apache/docs/index.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. certbot-apache documentation master file, created by - sphinx-quickstart on Sun Oct 18 13:39:26 2015. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to certbot-apache's documentation! -============================================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - -.. toctree:: - :maxdepth: 1 - - api - - -.. automodule:: certbot_apache - :members: - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/certbot-apache/docs/make.bat b/certbot-apache/docs/make.bat deleted file mode 100644 index 3a7818940..000000000 --- a/certbot-apache/docs/make.bat +++ /dev/null @@ -1,263 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - echo. coverage to run coverage check of the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -REM Check if sphinx-build is available and fallback to Python version if any -%SPHINXBUILD% 2> nul -if errorlevel 9009 goto sphinx_python -goto sphinx_ok - -:sphinx_python - -set SPHINXBUILD=python -m sphinx.__init__ -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -:sphinx_ok - - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\certbot-apache.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\certbot-apache.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "coverage" ( - %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage - if errorlevel 1 exit /b 1 - echo. - echo.Testing of coverage in the sources finished, look at the ^ -results in %BUILDDIR%/coverage/python.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/certbot-apache/local-oldest-requirements.txt b/certbot-apache/local-oldest-requirements.txt index 1ee716cd6..cf61c15a5 100644 --- a/certbot-apache/local-oldest-requirements.txt +++ b/certbot-apache/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.29.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-apache/readthedocs.org.requirements.txt b/certbot-apache/readthedocs.org.requirements.txt deleted file mode 100644 index fe30ab1dc..000000000 --- a/certbot-apache/readthedocs.org.requirements.txt +++ /dev/null @@ -1,12 +0,0 @@ -# readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation -# dependencies), but it allows to specify a requirements.txt file at -# https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) - -# Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead - --e acme --e . --e certbot-apache[docs] diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index 5895ec810..b676330c6 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -1,16 +1,16 @@ -from setuptools import setup -from setuptools import find_packages -from setuptools.command.test import test as TestCommand import sys +from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.29.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'mock', 'python-augeas', 'setuptools', @@ -18,11 +18,6 @@ install_requires = [ 'zope.interface', ] -docs_extras = [ - 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags - 'sphinx_rtd_theme', -] - class PyTest(TestCommand): user_options = [] @@ -74,12 +69,9 @@ setup( packages=find_packages(), include_package_data=True, install_requires=install_requires, - extras_require={ - 'docs': docs_extras, - }, entry_points={ 'certbot.plugins': [ - 'apache = certbot_apache.entrypoint:ENTRYPOINT', + 'apache = certbot_apache._internal.entrypoint:ENTRYPOINT', ], }, test_suite='certbot_apache', diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/NEEDED.txt b/certbot-apache/tests/apache-conf-files/NEEDED.txt similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/NEEDED.txt rename to certbot-apache/tests/apache-conf-files/NEEDED.txt diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/apache-conf-test b/certbot-apache/tests/apache-conf-files/apache-conf-test similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/apache-conf-test rename to certbot-apache/tests/apache-conf-files/apache-conf-test diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/apache-conf-test-pebble.py b/certbot-apache/tests/apache-conf-files/apache-conf-test-pebble.py similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/apache-conf-test-pebble.py rename to certbot-apache/tests/apache-conf-files/apache-conf-test-pebble.py diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/failing/missing-double-quote-1724.conf b/certbot-apache/tests/apache-conf-files/failing/missing-double-quote-1724.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/failing/missing-double-quote-1724.conf rename to certbot-apache/tests/apache-conf-files/failing/missing-double-quote-1724.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/failing/multivhost-1093.conf b/certbot-apache/tests/apache-conf-files/failing/multivhost-1093.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/failing/multivhost-1093.conf rename to certbot-apache/tests/apache-conf-files/failing/multivhost-1093.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/failing/multivhost-1093b.conf b/certbot-apache/tests/apache-conf-files/failing/multivhost-1093b.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/failing/multivhost-1093b.conf rename to certbot-apache/tests/apache-conf-files/failing/multivhost-1093b.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/1626-1531.conf b/certbot-apache/tests/apache-conf-files/passing/1626-1531.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/1626-1531.conf rename to certbot-apache/tests/apache-conf-files/passing/1626-1531.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/README.modules b/certbot-apache/tests/apache-conf-files/passing/README.modules similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/README.modules rename to certbot-apache/tests/apache-conf-files/passing/README.modules diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/anarcat-1531.conf b/certbot-apache/tests/apache-conf-files/passing/anarcat-1531.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/anarcat-1531.conf rename to certbot-apache/tests/apache-conf-files/passing/anarcat-1531.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/comment-continuations-2050.conf b/certbot-apache/tests/apache-conf-files/passing/comment-continuations-2050.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/comment-continuations-2050.conf rename to certbot-apache/tests/apache-conf-files/passing/comment-continuations-2050.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/drupal-errordocument-arg-1724.conf b/certbot-apache/tests/apache-conf-files/passing/drupal-errordocument-arg-1724.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/drupal-errordocument-arg-1724.conf rename to certbot-apache/tests/apache-conf-files/passing/drupal-errordocument-arg-1724.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/drupal-htaccess-1531.conf b/certbot-apache/tests/apache-conf-files/passing/drupal-htaccess-1531.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/drupal-htaccess-1531.conf rename to certbot-apache/tests/apache-conf-files/passing/drupal-htaccess-1531.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/escaped-space-arguments-2735.conf b/certbot-apache/tests/apache-conf-files/passing/escaped-space-arguments-2735.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/escaped-space-arguments-2735.conf rename to certbot-apache/tests/apache-conf-files/passing/escaped-space-arguments-2735.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/example-1755.conf b/certbot-apache/tests/apache-conf-files/passing/example-1755.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/example-1755.conf rename to certbot-apache/tests/apache-conf-files/passing/example-1755.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/example-ssl.conf b/certbot-apache/tests/apache-conf-files/passing/example-ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/example-ssl.conf rename to certbot-apache/tests/apache-conf-files/passing/example-ssl.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/example.conf b/certbot-apache/tests/apache-conf-files/passing/example.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/example.conf rename to certbot-apache/tests/apache-conf-files/passing/example.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/finalize-1243.apache2.conf.txt b/certbot-apache/tests/apache-conf-files/passing/finalize-1243.apache2.conf.txt similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/finalize-1243.apache2.conf.txt rename to certbot-apache/tests/apache-conf-files/passing/finalize-1243.apache2.conf.txt diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/finalize-1243.conf b/certbot-apache/tests/apache-conf-files/passing/finalize-1243.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/finalize-1243.conf rename to certbot-apache/tests/apache-conf-files/passing/finalize-1243.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/graphite-quote-1934.conf b/certbot-apache/tests/apache-conf-files/passing/graphite-quote-1934.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/graphite-quote-1934.conf rename to certbot-apache/tests/apache-conf-files/passing/graphite-quote-1934.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/ipv6-1143.conf b/certbot-apache/tests/apache-conf-files/passing/ipv6-1143.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/ipv6-1143.conf rename to certbot-apache/tests/apache-conf-files/passing/ipv6-1143.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/ipv6-1143b.conf b/certbot-apache/tests/apache-conf-files/passing/ipv6-1143b.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/ipv6-1143b.conf rename to certbot-apache/tests/apache-conf-files/passing/ipv6-1143b.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/ipv6-1143c.conf b/certbot-apache/tests/apache-conf-files/passing/ipv6-1143c.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/ipv6-1143c.conf rename to certbot-apache/tests/apache-conf-files/passing/ipv6-1143c.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/ipv6-1143d.conf b/certbot-apache/tests/apache-conf-files/passing/ipv6-1143d.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/ipv6-1143d.conf rename to certbot-apache/tests/apache-conf-files/passing/ipv6-1143d.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/missing-quote-1724.conf b/certbot-apache/tests/apache-conf-files/passing/missing-quote-1724.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/missing-quote-1724.conf rename to certbot-apache/tests/apache-conf-files/passing/missing-quote-1724.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/modmacro-1385.conf b/certbot-apache/tests/apache-conf-files/passing/modmacro-1385.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/modmacro-1385.conf rename to certbot-apache/tests/apache-conf-files/passing/modmacro-1385.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/owncloud-1264.conf b/certbot-apache/tests/apache-conf-files/passing/owncloud-1264.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/owncloud-1264.conf rename to certbot-apache/tests/apache-conf-files/passing/owncloud-1264.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/rewrite-quote-1960.conf b/certbot-apache/tests/apache-conf-files/passing/rewrite-quote-1960.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/rewrite-quote-1960.conf rename to certbot-apache/tests/apache-conf-files/passing/rewrite-quote-1960.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/roundcube-1222.conf b/certbot-apache/tests/apache-conf-files/passing/roundcube-1222.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/roundcube-1222.conf rename to certbot-apache/tests/apache-conf-files/passing/roundcube-1222.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/section-continuations-2525.conf b/certbot-apache/tests/apache-conf-files/passing/section-continuations-2525.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/section-continuations-2525.conf rename to certbot-apache/tests/apache-conf-files/passing/section-continuations-2525.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/section-empty-continuations-2731.conf b/certbot-apache/tests/apache-conf-files/passing/section-empty-continuations-2731.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/section-empty-continuations-2731.conf rename to certbot-apache/tests/apache-conf-files/passing/section-empty-continuations-2731.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/semacode-1598.conf b/certbot-apache/tests/apache-conf-files/passing/semacode-1598.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/semacode-1598.conf rename to certbot-apache/tests/apache-conf-files/passing/semacode-1598.conf diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/sslrequire-wordlist-1827.htaccess b/certbot-apache/tests/apache-conf-files/passing/sslrequire-wordlist-1827.htaccess similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/sslrequire-wordlist-1827.htaccess rename to certbot-apache/tests/apache-conf-files/passing/sslrequire-wordlist-1827.htaccess diff --git a/certbot-apache/certbot_apache/tests/apache-conf-files/passing/two-blocks-one-line-1693.conf b/certbot-apache/tests/apache-conf-files/passing/two-blocks-one-line-1693.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/apache-conf-files/passing/two-blocks-one-line-1693.conf rename to certbot-apache/tests/apache-conf-files/passing/two-blocks-one-line-1693.conf diff --git a/certbot-apache/certbot_apache/tests/autohsts_test.py b/certbot-apache/tests/autohsts_test.py similarity index 81% rename from certbot-apache/certbot_apache/tests/autohsts_test.py rename to certbot-apache/tests/autohsts_test.py index 2d22df289..c9901ecdb 100644 --- a/certbot-apache/certbot_apache/tests/autohsts_test.py +++ b/certbot-apache/tests/autohsts_test.py @@ -1,14 +1,14 @@ -# pylint: disable=too-many-public-methods,too-many-lines -"""Test for certbot_apache.configurator AutoHSTS functionality""" +# pylint: disable=too-many-lines +"""Test for certbot_apache._internal.configurator AutoHSTS functionality""" import re import unittest + import mock -# six is used in mock.patch() -import six # pylint: disable=unused-import +import six # pylint: disable=unused-import # six is used in mock.patch() from certbot import errors -from certbot_apache import constants -from certbot_apache.tests import util +from certbot_apache._internal import constants +import util class AutoHSTSTest(util.ApacheTest): @@ -39,24 +39,24 @@ class AutoHSTSTest(util.ApacheTest): head.replace("arg[3]", "arg[4]")) return None # pragma: no cover - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") - @mock.patch("certbot_apache.configurator.ApacheConfigurator.enable_mod") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.enable_mod") def test_autohsts_enable_headers_mod(self, mock_enable, _restart): self.config.parser.modules.discard("headers_module") self.config.parser.modules.discard("mod_header.c") self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com"]) self.assertTrue(mock_enable.called) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") def test_autohsts_deploy_already_exists(self, _restart): self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com"]) self.assertRaises(errors.PluginEnhancementAlreadyPresent, self.config.enable_autohsts, mock.MagicMock(), ["ocspvhost.com"]) - @mock.patch("certbot_apache.constants.AUTOHSTS_FREQ", 0) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") - @mock.patch("certbot_apache.configurator.ApacheConfigurator.prepare") + @mock.patch("certbot_apache._internal.constants.AUTOHSTS_FREQ", 0) + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.prepare") def test_autohsts_increase(self, mock_prepare, _mock_restart): self.config._prepared = False maxage = "\"max-age={0}\"" @@ -74,8 +74,8 @@ class AutoHSTSTest(util.ApacheTest): inc_val) self.assertTrue(mock_prepare.called) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") - @mock.patch("certbot_apache.configurator.ApacheConfigurator._autohsts_increase") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator._autohsts_increase") def test_autohsts_increase_noop(self, mock_increase, _restart): maxage = "\"max-age={0}\"" initial_val = maxage.format(constants.AUTOHSTS_STEPS[0]) @@ -89,8 +89,8 @@ class AutoHSTSTest(util.ApacheTest): self.assertFalse(mock_increase.called) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") - @mock.patch("certbot_apache.constants.AUTOHSTS_FREQ", 0) + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.constants.AUTOHSTS_FREQ", 0) def test_autohsts_increase_no_header(self, _restart): self.config.enable_autohsts(mock.MagicMock(), ["ocspvhost.com"]) # Remove the header @@ -102,8 +102,8 @@ class AutoHSTSTest(util.ApacheTest): self.config.update_autohsts, mock.MagicMock()) - @mock.patch("certbot_apache.constants.AUTOHSTS_FREQ", 0) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.constants.AUTOHSTS_FREQ", 0) + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") def test_autohsts_increase_and_make_permanent(self, _mock_restart): maxage = "\"max-age={0}\"" max_val = maxage.format(constants.AUTOHSTS_PERMANENT) @@ -141,18 +141,18 @@ class AutoHSTSTest(util.ApacheTest): # Make sure that the execution does not continue when no entries in store self.assertFalse(self.config.storage.put.called) - @mock.patch("certbot_apache.display_ops.select_vhost") + @mock.patch("certbot_apache._internal.display_ops.select_vhost") def test_autohsts_no_ssl_vhost(self, mock_select): mock_select.return_value = self.vh_truth[0] - with mock.patch("certbot_apache.configurator.logger.warning") as mock_log: + with mock.patch("certbot_apache._internal.configurator.logger.warning") as mock_log: self.assertRaises(errors.PluginError, self.config.enable_autohsts, mock.MagicMock(), "invalid.example.com") self.assertTrue( "Certbot was not able to find SSL" in mock_log.call_args[0][0]) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") - @mock.patch("certbot_apache.configurator.ApacheConfigurator.add_vhost_id") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.add_vhost_id") def test_autohsts_dont_enhance_twice(self, mock_id, _restart): mock_id.return_value = "1234567" self.config.enable_autohsts(mock.MagicMock(), @@ -177,7 +177,7 @@ class AutoHSTSTest(util.ApacheTest): self.config._autohsts_fetch_state() self.config._autohsts["orphan_id"] = {"laststep": 999, "timestamp": 0} self.config._autohsts_save_state() - with mock.patch("certbot_apache.configurator.logger.warning") as mock_log: + with mock.patch("certbot_apache._internal.configurator.logger.warning") as mock_log: self.config.deploy_autohsts(mock.MagicMock()) self.assertTrue(mock_log.called) self.assertTrue( diff --git a/certbot-apache/certbot_apache/tests/centos6_test.py b/certbot-apache/tests/centos6_test.py similarity index 97% rename from certbot-apache/certbot_apache/tests/centos6_test.py rename to certbot-apache/tests/centos6_test.py index 3c427ee91..15d086600 100644 --- a/certbot-apache/certbot_apache/tests/centos6_test.py +++ b/certbot-apache/tests/centos6_test.py @@ -1,13 +1,12 @@ -"""Test for certbot_apache.configurator for CentOS 6 overrides""" +"""Test for certbot_apache._internal.configurator for CentOS 6 overrides""" import unittest from certbot.compat import os from certbot.errors import MisconfigurationError - -from certbot_apache import obj -from certbot_apache import override_centos -from certbot_apache import parser -from certbot_apache.tests import util +from certbot_apache._internal import obj +from certbot_apache._internal import override_centos +from certbot_apache._internal import parser +import util def get_vh_truth(temp_dir, config_name): diff --git a/certbot-apache/certbot_apache/tests/centos_test.py b/certbot-apache/tests/centos_test.py similarity index 91% rename from certbot-apache/certbot_apache/tests/centos_test.py rename to certbot-apache/tests/centos_test.py index dddbf489e..8959d73b8 100644 --- a/certbot-apache/certbot_apache/tests/centos_test.py +++ b/certbot-apache/tests/centos_test.py @@ -1,4 +1,4 @@ -"""Test for certbot_apache.configurator for Centos overrides""" +"""Test for certbot_apache._internal.configurator for Centos overrides""" import unittest import mock @@ -6,10 +6,9 @@ import mock from certbot import errors from certbot.compat import filesystem from certbot.compat import os - -from certbot_apache import obj -from certbot_apache import override_centos -from certbot_apache.tests import util +from certbot_apache._internal import obj +from certbot_apache._internal import override_centos +import util def get_vh_truth(temp_dir, config_name): @@ -55,7 +54,7 @@ class FedoraRestartTest(util.ApacheTest): self.config.config_test() def test_non_fedora_error(self): - c_test = "certbot_apache.configurator.ApacheConfigurator.config_test" + c_test = "certbot_apache._internal.configurator.ApacheConfigurator.config_test" with mock.patch(c_test) as mock_test: mock_test.side_effect = errors.MisconfigurationError with mock.patch("certbot.util.get_os_info") as mock_info: @@ -64,7 +63,7 @@ class FedoraRestartTest(util.ApacheTest): self.config.config_test) def test_fedora_restart_error(self): - c_test = "certbot_apache.configurator.ApacheConfigurator.config_test" + c_test = "certbot_apache._internal.configurator.ApacheConfigurator.config_test" with mock.patch(c_test) as mock_test: # First call raises error, second doesn't mock_test.side_effect = [errors.MisconfigurationError, ''] @@ -74,7 +73,7 @@ class FedoraRestartTest(util.ApacheTest): self._run_fedora_test) def test_fedora_restart(self): - c_test = "certbot_apache.configurator.ApacheConfigurator.config_test" + c_test = "certbot_apache._internal.configurator.ApacheConfigurator.config_test" with mock.patch(c_test) as mock_test: with mock.patch("certbot.util.run_script") as mock_run: # First call raises error, second doesn't @@ -107,7 +106,7 @@ class MultipleVhostsTestCentOS(util.ApacheTest): def test_get_parser(self): self.assertIsInstance(self.config.parser, override_centos.CentOSParser) - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_opportunistic_httpd_runtime_parsing(self, mock_get): define_val = ( 'Define: TEST1\n' @@ -156,7 +155,7 @@ class MultipleVhostsTestCentOS(util.ApacheTest): raise Exception("Missed: %s" % vhost) # pragma: no cover self.assertEqual(found, 2) - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_get_sysconfig_vars(self, mock_cfg): """Make sure we read the sysconfig OPTIONS variable correctly""" # Return nothing for the process calls @@ -177,13 +176,13 @@ class MultipleVhostsTestCentOS(util.ApacheTest): self.assertTrue("MOCK_NOSEP" in self.config.parser.variables.keys()) self.assertEqual("NOSEP_VAL", self.config.parser.variables["NOSEP_TWO"]) - @mock.patch("certbot_apache.configurator.util.run_script") + @mock.patch("certbot_apache._internal.configurator.util.run_script") def test_alt_restart_works(self, mock_run_script): mock_run_script.side_effect = [None, errors.SubprocessError, None] self.config.restart() self.assertEqual(mock_run_script.call_count, 3) - @mock.patch("certbot_apache.configurator.util.run_script") + @mock.patch("certbot_apache._internal.configurator.util.run_script") def test_alt_restart_errors(self, mock_run_script): mock_run_script.side_effect = [None, errors.SubprocessError, diff --git a/certbot-apache/certbot_apache/tests/complex_parsing_test.py b/certbot-apache/tests/complex_parsing_test.py similarity index 97% rename from certbot-apache/certbot_apache/tests/complex_parsing_test.py rename to certbot-apache/tests/complex_parsing_test.py index 8712eb5bf..8b795b0b6 100644 --- a/certbot-apache/certbot_apache/tests/complex_parsing_test.py +++ b/certbot-apache/tests/complex_parsing_test.py @@ -1,11 +1,10 @@ -"""Tests for certbot_apache.parser.""" +"""Tests for certbot_apache._internal.parser.""" import shutil import unittest from certbot import errors from certbot.compat import os - -from certbot_apache.tests import util +import util class ComplexParserTest(util.ParserTest): @@ -88,7 +87,7 @@ class ComplexParserTest(util.ParserTest): def verify_fnmatch(self, arg, hit=True): """Test if Include was correctly parsed.""" - from certbot_apache import parser + from certbot_apache._internal import parser self.parser.add_dir(parser.get_aug_path(self.parser.loc["default"]), "Include", [arg]) if hit: diff --git a/certbot-apache/certbot_apache/tests/configurator_reverter_test.py b/certbot-apache/tests/configurator_reverter_test.py similarity index 96% rename from certbot-apache/certbot_apache/tests/configurator_reverter_test.py rename to certbot-apache/tests/configurator_reverter_test.py index f3c418a3a..ad8e73347 100644 --- a/certbot-apache/certbot_apache/tests/configurator_reverter_test.py +++ b/certbot-apache/tests/configurator_reverter_test.py @@ -1,12 +1,11 @@ -"""Test for certbot_apache.configurator implementations of reverter""" +"""Test for certbot_apache._internal.configurator implementations of reverter""" import shutil import unittest import mock from certbot import errors - -from certbot_apache.tests import util +import util class ConfiguratorReverterTest(util.ApacheTest): diff --git a/certbot-apache/certbot_apache/tests/configurator_test.py b/certbot-apache/tests/configurator_test.py similarity index 93% rename from certbot-apache/certbot_apache/tests/configurator_test.py rename to certbot-apache/tests/configurator_test.py index 52c5b437c..9fab5ea5d 100644 --- a/certbot-apache/certbot_apache/tests/configurator_test.py +++ b/certbot-apache/tests/configurator_test.py @@ -1,5 +1,5 @@ -# pylint: disable=too-many-public-methods,too-many-lines -"""Test for certbot_apache.configurator.""" +# pylint: disable=too-many-lines +"""Test for certbot_apache._internal.configurator.""" import copy import shutil import socket @@ -7,24 +7,21 @@ import tempfile import unittest import mock -# six is used in mock.patch() -import six # pylint: disable=unused-import +import six # pylint: disable=unused-import # six is used in mock.patch() from acme import challenges - from certbot import achallenges from certbot import crypto_util from certbot import errors -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os from certbot.tests import acme_util from certbot.tests import util as certbot_util - -from certbot_apache import apache_util -from certbot_apache import constants -from certbot_apache import obj -from certbot_apache import parser -from certbot_apache.tests import util +from certbot_apache._internal import apache_util +from certbot_apache._internal import constants +from certbot_apache._internal import obj +from certbot_apache._internal import parser +import util class MultipleVhostsTest(util.ApacheTest): @@ -45,13 +42,13 @@ class MultipleVhostsTest(util.ApacheTest): def mocked_deploy_cert(*args, **kwargs): """a helper to mock a deployed cert""" - g_mod = "certbot_apache.configurator.ApacheConfigurator.enable_mod" + g_mod = "certbot_apache._internal.configurator.ApacheConfigurator.enable_mod" with mock.patch(g_mod): config.real_deploy_cert(*args, **kwargs) self.config.deploy_cert = mocked_deploy_cert return self.config - @mock.patch("certbot_apache.configurator.path_surgery") + @mock.patch("certbot_apache._internal.configurator.path_surgery") def test_prepare_no_install(self, mock_surgery): silly_path = {"PATH": "/tmp/nothingness2342"} mock_surgery.return_value = False @@ -59,8 +56,8 @@ class MultipleVhostsTest(util.ApacheTest): self.assertRaises(errors.NoInstallationError, self.config.prepare) self.assertEqual(mock_surgery.call_count, 1) - @mock.patch("certbot_apache.parser.ApacheParser") - @mock.patch("certbot_apache.configurator.util.exe_exists") + @mock.patch("certbot_apache._internal.parser.ApacheParser") + @mock.patch("certbot_apache._internal.configurator.util.exe_exists") def test_prepare_version(self, mock_exe_exists, _): mock_exe_exists.return_value = True self.config.version = None @@ -76,8 +73,8 @@ class MultipleVhostsTest(util.ApacheTest): os.remove(os.path.join(server_root, ".certbot.lock")) certbot_util.lock_and_call(self._test_prepare_locked, server_root) - @mock.patch("certbot_apache.parser.ApacheParser") - @mock.patch("certbot_apache.configurator.util.exe_exists") + @mock.patch("certbot_apache._internal.parser.ApacheParser") + @mock.patch("certbot_apache._internal.configurator.util.exe_exists") def _test_prepare_locked(self, unused_parser, unused_exe_exists): try: self.config.prepare() @@ -89,13 +86,13 @@ class MultipleVhostsTest(util.ApacheTest): self.fail("Exception wasn't raised!") def test_add_parser_arguments(self): # pylint: disable=no-self-use - from certbot_apache.configurator import ApacheConfigurator + from certbot_apache._internal.configurator import ApacheConfigurator # Weak test.. ApacheConfigurator.add_parser_arguments(mock.MagicMock()) def test_docs_parser_arguments(self): os.environ["CERTBOT_DOCS"] = "1" - from certbot_apache.configurator import ApacheConfigurator + from certbot_apache._internal.configurator import ApacheConfigurator mock_add = mock.MagicMock() ApacheConfigurator.add_parser_arguments(mock_add) parserargs = ["server_root", "enmod", "dismod", "le_vhost_ext", @@ -121,13 +118,13 @@ class MultipleVhostsTest(util.ApacheTest): del os.environ["CERTBOT_DOCS"] def test_add_parser_arguments_all_configurators(self): # pylint: disable=no-self-use - from certbot_apache.entrypoint import OVERRIDE_CLASSES + from certbot_apache._internal.entrypoint import OVERRIDE_CLASSES for cls in OVERRIDE_CLASSES.values(): cls.add_parser_arguments(mock.MagicMock()) def test_all_configurators_defaults_defined(self): - from certbot_apache.entrypoint import OVERRIDE_CLASSES - from certbot_apache.configurator import ApacheConfigurator + from certbot_apache._internal.entrypoint import OVERRIDE_CLASSES + from certbot_apache._internal.configurator import ApacheConfigurator parameters = set(ApacheConfigurator.OS_DEFAULTS.keys()) for cls in OVERRIDE_CLASSES.values(): self.assertTrue(parameters.issubset(set(cls.OS_DEFAULTS.keys()))) @@ -149,7 +146,7 @@ class MultipleVhostsTest(util.ApacheTest): )) @certbot_util.patch_get_utility() - @mock.patch("certbot_apache.configurator.socket.gethostbyaddr") + @mock.patch("certbot_apache._internal.configurator.socket.gethostbyaddr") def test_get_all_names_addrs(self, mock_gethost, mock_getutility): mock_gethost.side_effect = [("google.com", "", ""), socket.error] mock_utility = mock_getutility() @@ -175,7 +172,7 @@ class MultipleVhostsTest(util.ApacheTest): self.assertEqual(self.config._create_vhost("nonexistent"), None) # pylint: disable=protected-access def test_get_aug_internal_path(self): - from certbot_apache.apache_util import get_internal_aug_path + from certbot_apache._internal.apache_util import get_internal_aug_path internal_paths = [ "Virtualhost", "IfModule/VirtualHost", "VirtualHost", "VirtualHost", "Macro/VirtualHost", "IfModule/VirtualHost", "VirtualHost", @@ -220,26 +217,26 @@ class MultipleVhostsTest(util.ApacheTest): # Handle case of non-debian layout get_virtual_hosts with mock.patch( - "certbot_apache.configurator.ApacheConfigurator.conf" + "certbot_apache._internal.configurator.ApacheConfigurator.conf" ) as mock_conf: mock_conf.return_value = False vhs = self.config.get_virtual_hosts() self.assertEqual(len(vhs), 12) - @mock.patch("certbot_apache.display_ops.select_vhost") + @mock.patch("certbot_apache._internal.display_ops.select_vhost") def test_choose_vhost_none_avail(self, mock_select): mock_select.return_value = None self.assertRaises( errors.PluginError, self.config.choose_vhost, "none.com") - @mock.patch("certbot_apache.display_ops.select_vhost") + @mock.patch("certbot_apache._internal.display_ops.select_vhost") def test_choose_vhost_select_vhost_ssl(self, mock_select): mock_select.return_value = self.vh_truth[1] self.assertEqual( self.vh_truth[1], self.config.choose_vhost("none.com")) - @mock.patch("certbot_apache.display_ops.select_vhost") - @mock.patch("certbot_apache.obj.VirtualHost.conflicts") + @mock.patch("certbot_apache._internal.display_ops.select_vhost") + @mock.patch("certbot_apache._internal.obj.VirtualHost.conflicts") def test_choose_vhost_select_vhost_non_ssl(self, mock_conf, mock_select): mock_select.return_value = self.vh_truth[0] mock_conf.return_value = False @@ -252,8 +249,8 @@ class MultipleVhostsTest(util.ApacheTest): self.assertFalse(self.vh_truth[0].ssl) self.assertTrue(chosen_vhost.ssl) - @mock.patch("certbot_apache.configurator.ApacheConfigurator._find_best_vhost") - @mock.patch("certbot_apache.parser.ApacheParser.add_dir") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator._find_best_vhost") + @mock.patch("certbot_apache._internal.parser.ApacheParser.add_dir") def test_choose_vhost_and_servername_addition(self, mock_add, mock_find): ret_vh = self.vh_truth[8] ret_vh.enabled = False @@ -261,13 +258,13 @@ class MultipleVhostsTest(util.ApacheTest): self.config.choose_vhost("whatever.com") self.assertTrue(mock_add.called) - @mock.patch("certbot_apache.display_ops.select_vhost") + @mock.patch("certbot_apache._internal.display_ops.select_vhost") def test_choose_vhost_select_vhost_with_temp(self, mock_select): mock_select.return_value = self.vh_truth[0] chosen_vhost = self.config.choose_vhost("none.com", create_if_no_ssl=False) self.assertEqual(self.vh_truth[0], chosen_vhost) - @mock.patch("certbot_apache.display_ops.select_vhost") + @mock.patch("certbot_apache._internal.display_ops.select_vhost") def test_choose_vhost_select_vhost_conflicting_non_ssl(self, mock_select): mock_select.return_value = self.vh_truth[3] conflicting_vhost = obj.VirtualHost( @@ -784,8 +781,8 @@ class MultipleVhostsTest(util.ApacheTest): self.config._add_name_vhost_if_necessary(self.vh_truth[0]) self.assertEqual(self.config.add_name_vhost.call_count, 2) - @mock.patch("certbot_apache.configurator.http_01.ApacheHttp01.perform") - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.configurator.http_01.ApacheHttp01.perform") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") def test_perform(self, mock_restart, mock_http_perform): # Only tests functionality specific to configurator.perform # Note: As more challenges are offered this will have to be expanded @@ -801,8 +798,8 @@ class MultipleVhostsTest(util.ApacheTest): self.assertEqual(mock_restart.call_count, 1) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_cleanup(self, mock_cfg, mock_restart): mock_cfg.return_value = "" _, achalls = self.get_key_and_achalls() @@ -817,8 +814,8 @@ class MultipleVhostsTest(util.ApacheTest): else: self.assertFalse(mock_restart.called) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.restart") - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.restart") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_cleanup_no_errors(self, mock_cfg, mock_restart): mock_cfg.return_value = "" _, achalls = self.get_key_and_achalls() @@ -855,11 +852,11 @@ class MultipleVhostsTest(util.ApacheTest): mock_script.side_effect = errors.SubprocessError("Can't find program") self.assertRaises(errors.PluginError, self.config.get_version) - @mock.patch("certbot_apache.configurator.util.run_script") + @mock.patch("certbot_apache._internal.configurator.util.run_script") def test_restart(self, _): self.config.restart() - @mock.patch("certbot_apache.configurator.util.run_script") + @mock.patch("certbot_apache._internal.configurator.util.run_script") def test_restart_bad_process(self, mock_run_script): mock_run_script.side_effect = [None, errors.SubprocessError] @@ -902,8 +899,8 @@ class MultipleVhostsTest(util.ApacheTest): self.assertEqual(self.vh_truth[0].name, res.name) self.assertEqual(self.vh_truth[0].aliases, res.aliases) - @mock.patch("certbot_apache.configurator.ApacheConfigurator._get_http_vhost") - @mock.patch("certbot_apache.display_ops.select_vhost") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator._get_http_vhost") + @mock.patch("certbot_apache._internal.display_ops.select_vhost") @mock.patch("certbot.util.exe_exists") def test_enhance_unknown_vhost(self, mock_exe, mock_sel_vhost, mock_get): self.config.parser.modules.add("rewrite_module") @@ -926,7 +923,7 @@ class MultipleVhostsTest(util.ApacheTest): self.config.enhance, "certbot.demo", "unknown_enhancement") def test_enhance_no_ssl_vhost(self): - with mock.patch("certbot_apache.configurator.logger.warning") as mock_log: + with mock.patch("certbot_apache._internal.configurator.logger.warning") as mock_log: self.assertRaises(errors.PluginError, self.config.enhance, "certbot.demo", "redirect") # Check that correct logger.warning was printed @@ -1231,7 +1228,7 @@ class MultipleVhostsTest(util.ApacheTest): self.config.choose_vhost("red.blue.purple.com") self.config.enhance("red.blue.purple.com", "redirect") - verify_no_redirect = ("certbot_apache.configurator." + verify_no_redirect = ("certbot_apache._internal.configurator." "ApacheConfigurator._verify_no_certbot_redirect") with mock.patch(verify_no_redirect) as mock_verify: self.config.enhance("green.blue.purple.com", "redirect") @@ -1333,8 +1330,8 @@ class MultipleVhostsTest(util.ApacheTest): self.config.parser.modules.add("socache_shmcb_module") tmp_path = filesystem.realpath(tempfile.mkdtemp("vhostroot")) filesystem.chmod(tmp_path, 0o755) - mock_p = "certbot_apache.configurator.ApacheConfigurator._get_ssl_vhost_path" - mock_a = "certbot_apache.parser.ApacheParser.add_include" + mock_p = "certbot_apache._internal.configurator.ApacheConfigurator._get_ssl_vhost_path" + mock_a = "certbot_apache._internal.parser.ApacheParser.add_include" with mock.patch(mock_p) as mock_path: mock_path.return_value = os.path.join(tmp_path, "whatever.conf") @@ -1347,7 +1344,7 @@ class MultipleVhostsTest(util.ApacheTest): self.assertTrue(mock_add.called) shutil.rmtree(tmp_path) - @mock.patch("certbot_apache.parser.ApacheParser.parsed_in_original") + @mock.patch("certbot_apache._internal.parser.ApacheParser.parsed_in_original") def test_choose_vhost_and_servername_addition_parsed(self, mock_parsed): ret_vh = self.vh_truth[8] ret_vh.enabled = True @@ -1369,7 +1366,7 @@ class MultipleVhostsTest(util.ApacheTest): def test_choose_vhosts_wildcard(self): # pylint: disable=protected-access - mock_path = "certbot_apache.display_ops.select_vhost_multiple" + mock_path = "certbot_apache._internal.display_ops.select_vhost_multiple" with mock.patch(mock_path) as mock_select_vhs: mock_select_vhs.return_value = [self.vh_truth[3]] vhs = self.config._choose_vhosts_wildcard("*.certbot.demo", @@ -1385,10 +1382,10 @@ class MultipleVhostsTest(util.ApacheTest): self.assertFalse(vhs[0] == self.vh_truth[3]) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.make_vhost_ssl") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.make_vhost_ssl") def test_choose_vhosts_wildcard_no_ssl(self, mock_makessl): # pylint: disable=protected-access - mock_path = "certbot_apache.display_ops.select_vhost_multiple" + mock_path = "certbot_apache._internal.display_ops.select_vhost_multiple" with mock.patch(mock_path) as mock_select_vhs: mock_select_vhs.return_value = [self.vh_truth[1]] vhs = self.config._choose_vhosts_wildcard("*.certbot.demo", @@ -1396,13 +1393,13 @@ class MultipleVhostsTest(util.ApacheTest): self.assertFalse(mock_makessl.called) self.assertEqual(vhs[0], self.vh_truth[1]) - @mock.patch("certbot_apache.configurator.ApacheConfigurator._vhosts_for_wildcard") - @mock.patch("certbot_apache.configurator.ApacheConfigurator.make_vhost_ssl") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator._vhosts_for_wildcard") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.make_vhost_ssl") def test_choose_vhosts_wildcard_already_ssl(self, mock_makessl, mock_vh_for_w): # pylint: disable=protected-access # Already SSL vhost mock_vh_for_w.return_value = [self.vh_truth[7]] - mock_path = "certbot_apache.display_ops.select_vhost_multiple" + mock_path = "certbot_apache._internal.display_ops.select_vhost_multiple" with mock.patch(mock_path) as mock_select_vhs: mock_select_vhs.return_value = [self.vh_truth[7]] vhs = self.config._choose_vhosts_wildcard("whatever", @@ -1423,7 +1420,7 @@ class MultipleVhostsTest(util.ApacheTest): mock_choose_vhosts = mock.MagicMock() mock_choose_vhosts.return_value = [self.vh_truth[7]] self.config._choose_vhosts_wildcard = mock_choose_vhosts - mock_d = "certbot_apache.configurator.ApacheConfigurator._deploy_cert" + mock_d = "certbot_apache._internal.configurator.ApacheConfigurator._deploy_cert" with mock.patch(mock_d) as mock_dep: self.config.deploy_cert("*.wildcard.example.org", "/tmp/path", "/tmp/path", "/tmp/path", "/tmp/path") @@ -1431,7 +1428,7 @@ class MultipleVhostsTest(util.ApacheTest): self.assertEqual(len(mock_dep.call_args_list), 1) self.assertEqual(self.vh_truth[7], mock_dep.call_args_list[0][0][0]) - @mock.patch("certbot_apache.display_ops.select_vhost_multiple") + @mock.patch("certbot_apache._internal.display_ops.select_vhost_multiple") def test_deploy_cert_wildcard_no_vhosts(self, mock_dialog): # pylint: disable=protected-access mock_dialog.return_value = [] @@ -1440,7 +1437,7 @@ class MultipleVhostsTest(util.ApacheTest): "*.wild.cat", "/tmp/path", "/tmp/path", "/tmp/path", "/tmp/path") - @mock.patch("certbot_apache.configurator.ApacheConfigurator._choose_vhosts_wildcard") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator._choose_vhosts_wildcard") def test_enhance_wildcard_after_install(self, mock_choose): # pylint: disable=protected-access self.config.parser.modules.add("mod_ssl.c") @@ -1451,7 +1448,7 @@ class MultipleVhostsTest(util.ApacheTest): "Upgrade-Insecure-Requests") self.assertFalse(mock_choose.called) - @mock.patch("certbot_apache.configurator.ApacheConfigurator._choose_vhosts_wildcard") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator._choose_vhosts_wildcard") def test_enhance_wildcard_no_install(self, mock_choose): self.vh_truth[3].ssl = True mock_choose.return_value = [self.vh_truth[3]] @@ -1528,7 +1525,7 @@ class AugeasVhostsTest(util.ApacheTest): chosen_vhost = self.config._create_vhost(path) self.assertTrue(chosen_vhost is None or chosen_vhost.path == path) - @mock.patch("certbot_apache.configurator.ApacheConfigurator._create_vhost") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator._create_vhost") def test_get_vhost_continue(self, mock_vhost): mock_vhost.return_value = None vhs = self.config.get_virtual_hosts() @@ -1540,18 +1537,18 @@ class AugeasVhostsTest(util.ApacheTest): for name in names: self.assertFalse(name in self.config.choose_vhost(name).aliases) - @mock.patch("certbot_apache.obj.VirtualHost.conflicts") + @mock.patch("certbot_apache._internal.obj.VirtualHost.conflicts") def test_choose_vhost_without_matching_wildcard(self, mock_conflicts): mock_conflicts.return_value = False - mock_path = "certbot_apache.display_ops.select_vhost" + mock_path = "certbot_apache._internal.display_ops.select_vhost" with mock.patch(mock_path, lambda _, vhosts: vhosts[0]): for name in ("a.example.net", "other.example.net"): self.assertTrue(name in self.config.choose_vhost(name).aliases) - @mock.patch("certbot_apache.obj.VirtualHost.conflicts") + @mock.patch("certbot_apache._internal.obj.VirtualHost.conflicts") def test_choose_vhost_wildcard_not_found(self, mock_conflicts): mock_conflicts.return_value = False - mock_path = "certbot_apache.display_ops.select_vhost" + mock_path = "certbot_apache._internal.display_ops.select_vhost" names = ( "abc.example.net", "not.there.tld", "aa.wildcard.tld" ) @@ -1563,7 +1560,7 @@ class AugeasVhostsTest(util.ApacheTest): self.assertEqual(mock_select.call_count - orig_cc, 1) def test_choose_vhost_wildcard_found(self): - mock_path = "certbot_apache.display_ops.select_vhost" + mock_path = "certbot_apache._internal.display_ops.select_vhost" names = ( "ab.example.net", "a.wildcard.tld", "yetanother.example.net" ) @@ -1617,7 +1614,7 @@ class MultiVhostsTest(util.ApacheTest): self.assertEqual(self.config.is_name_vhost(self.vh_truth[1]), self.config.is_name_vhost(ssl_vhost)) - mock_path = "certbot_apache.configurator.ApacheConfigurator._get_new_vh_path" + mock_path = "certbot_apache._internal.configurator.ApacheConfigurator._get_new_vh_path" with mock.patch(mock_path) as mock_getpath: mock_getpath.return_value = None self.assertRaises(errors.PluginError, self.config.make_vhost_ssl, @@ -1723,7 +1720,7 @@ class InstallSslOptionsConfTest(util.ApacheTest): self._assert_current_file() def test_prev_file_updates_to_current(self): - from certbot_apache.constants import ALL_SSL_OPTIONS_HASHES + from certbot_apache._internal.constants import ALL_SSL_OPTIONS_HASHES ALL_SSL_OPTIONS_HASHES.insert(0, "test_hash_does_not_match") with mock.patch('certbot.crypto_util.sha256sum') as mock_sha256: mock_sha256.return_value = ALL_SSL_OPTIONS_HASHES[0] @@ -1762,7 +1759,7 @@ class InstallSslOptionsConfTest(util.ApacheTest): self.assertFalse(mock_logger.warning.called) def test_current_file_hash_in_all_hashes(self): - from certbot_apache.constants import ALL_SSL_OPTIONS_HASHES + from certbot_apache._internal.constants import ALL_SSL_OPTIONS_HASHES self.assertTrue(self._current_ssl_options_hash() in ALL_SSL_OPTIONS_HASHES, "Constants.ALL_SSL_OPTIONS_HASHES must be appended" " with the sha256 hash of self.config.mod_ssl_conf when it is updated.") diff --git a/certbot-apache/certbot_apache/tests/debian_test.py b/certbot-apache/tests/debian_test.py similarity index 94% rename from certbot-apache/certbot_apache/tests/debian_test.py rename to certbot-apache/tests/debian_test.py index 54ced2d0b..6e63a9bd3 100644 --- a/certbot-apache/certbot_apache/tests/debian_test.py +++ b/certbot-apache/tests/debian_test.py @@ -1,4 +1,4 @@ -"""Test for certbot_apache.configurator for Debian overrides""" +"""Test for certbot_apache._internal.configurator for Debian overrides""" import shutil import unittest @@ -6,10 +6,9 @@ import mock from certbot import errors from certbot.compat import os - -from certbot_apache import apache_util -from certbot_apache import obj -from certbot_apache.tests import util +from certbot_apache._internal import apache_util +from certbot_apache._internal import obj +import util class MultipleVhostsTestDebian(util.ApacheTest): @@ -32,8 +31,8 @@ class MultipleVhostsTestDebian(util.ApacheTest): def mocked_deploy_cert(*args, **kwargs): """a helper to mock a deployed cert""" - g_mod = "certbot_apache.configurator.ApacheConfigurator.enable_mod" - d_mod = "certbot_apache.override_debian.DebianConfigurator.enable_mod" + g_mod = "certbot_apache._internal.configurator.ApacheConfigurator.enable_mod" + d_mod = "certbot_apache._internal.override_debian.DebianConfigurator.enable_mod" with mock.patch(g_mod): with mock.patch(d_mod): config.real_deploy_cert(*args, **kwargs) @@ -47,7 +46,7 @@ class MultipleVhostsTestDebian(util.ApacheTest): @mock.patch("certbot.util.run_script") @mock.patch("certbot.util.exe_exists") - @mock.patch("certbot_apache.parser.subprocess.Popen") + @mock.patch("certbot_apache._internal.parser.subprocess.Popen") def test_enable_mod(self, mock_popen, mock_exe_exists, mock_run_script): mock_popen().communicate.return_value = ("Define: DUMP_RUN_CFG", "") mock_popen().returncode = 0 @@ -196,7 +195,7 @@ class MultipleVhostsTestDebian(util.ApacheTest): def test_enable_site_call_parent(self): with mock.patch( - "certbot_apache.configurator.ApacheConfigurator.enable_site") as e_s: + "certbot_apache._internal.configurator.ApacheConfigurator.enable_site") as e_s: self.config.parser.root = "/tmp/nonexistent" vh = self.vh_truth[0] vh.enabled = False diff --git a/certbot-apache/certbot_apache/tests/display_ops_test.py b/certbot-apache/tests/display_ops_test.py similarity index 86% rename from certbot-apache/certbot_apache/tests/display_ops_test.py rename to certbot-apache/tests/display_ops_test.py index df5cdbac0..50bdc03cf 100644 --- a/certbot-apache/certbot_apache/tests/display_ops_test.py +++ b/certbot-apache/tests/display_ops_test.py @@ -1,22 +1,18 @@ -"""Test certbot_apache.display_ops.""" +"""Test certbot_apache._internal.display_ops.""" import unittest import mock from certbot import errors - from certbot.display import util as display_util - from certbot.tests import util as certbot_util - -from certbot_apache import obj - -from certbot_apache.display_ops import select_vhost_multiple -from certbot_apache.tests import util +from certbot_apache._internal import obj +from certbot_apache._internal.display_ops import select_vhost_multiple +import util class SelectVhostMultiTest(unittest.TestCase): - """Tests for certbot_apache.display_ops.select_vhost_multiple.""" + """Tests for certbot_apache._internal.display_ops.select_vhost_multiple.""" def setUp(self): self.base_dir = "/example_path" @@ -45,7 +41,7 @@ class SelectVhostMultiTest(unittest.TestCase): self.assertFalse(vhs) class SelectVhostTest(unittest.TestCase): - """Tests for certbot_apache.display_ops.select_vhost.""" + """Tests for certbot_apache._internal.display_ops.select_vhost.""" def setUp(self): self.base_dir = "/example_path" @@ -54,7 +50,7 @@ class SelectVhostTest(unittest.TestCase): @classmethod def _call(cls, vhosts): - from certbot_apache.display_ops import select_vhost + from certbot_apache._internal.display_ops import select_vhost return select_vhost("example.com", vhosts) @certbot_util.patch_get_utility() @@ -81,9 +77,9 @@ class SelectVhostTest(unittest.TestCase): def test_no_vhosts(self): self.assertEqual(self._call([]), None) - @mock.patch("certbot_apache.display_ops.display_util") + @mock.patch("certbot_apache._internal.display_ops.display_util") @certbot_util.patch_get_utility() - @mock.patch("certbot_apache.display_ops.logger") + @mock.patch("certbot_apache._internal.display_ops.logger") def test_small_display(self, mock_logger, mock_util, mock_display_util): mock_display_util.WIDTH = 20 mock_util().menu.return_value = (display_util.OK, 0) diff --git a/certbot-apache/certbot_apache/tests/entrypoint_test.py b/certbot-apache/tests/entrypoint_test.py similarity index 90% rename from certbot-apache/certbot_apache/tests/entrypoint_test.py rename to certbot-apache/tests/entrypoint_test.py index 9adcd46dc..04c393bdf 100644 --- a/certbot-apache/certbot_apache/tests/entrypoint_test.py +++ b/certbot-apache/tests/entrypoint_test.py @@ -1,10 +1,10 @@ -"""Test for certbot_apache.entrypoint for override class resolution""" +"""Test for certbot_apache._internal.entrypoint for override class resolution""" import unittest import mock -from certbot_apache import configurator -from certbot_apache import entrypoint +from certbot_apache._internal import configurator +from certbot_apache._internal import entrypoint class EntryPointTest(unittest.TestCase): diff --git a/certbot-apache/certbot_apache/tests/fedora_test.py b/certbot-apache/tests/fedora_test.py similarity index 91% rename from certbot-apache/certbot_apache/tests/fedora_test.py rename to certbot-apache/tests/fedora_test.py index 4d3f3a313..2bfd6babb 100644 --- a/certbot-apache/certbot_apache/tests/fedora_test.py +++ b/certbot-apache/tests/fedora_test.py @@ -1,4 +1,4 @@ -"""Test for certbot_apache.configurator for Fedora 29+ overrides""" +"""Test for certbot_apache._internal.configurator for Fedora 29+ overrides""" import unittest import mock @@ -6,10 +6,9 @@ import mock from certbot import errors from certbot.compat import filesystem from certbot.compat import os - -from certbot_apache import obj -from certbot_apache import override_fedora -from certbot_apache.tests import util +from certbot_apache._internal import obj +from certbot_apache._internal import override_fedora +import util def get_vh_truth(temp_dir, config_name): @@ -58,7 +57,7 @@ class FedoraRestartTest(util.ApacheTest): self.config.config_test() def test_fedora_restart_error(self): - c_test = "certbot_apache.configurator.ApacheConfigurator.config_test" + c_test = "certbot_apache._internal.configurator.ApacheConfigurator.config_test" with mock.patch(c_test) as mock_test: # First call raises error, second doesn't mock_test.side_effect = [errors.MisconfigurationError, ''] @@ -68,7 +67,7 @@ class FedoraRestartTest(util.ApacheTest): self._run_fedora_test) def test_fedora_restart(self): - c_test = "certbot_apache.configurator.ApacheConfigurator.config_test" + c_test = "certbot_apache._internal.configurator.ApacheConfigurator.config_test" with mock.patch(c_test) as mock_test: with mock.patch("certbot.util.run_script") as mock_run: # First call raises error, second doesn't @@ -101,7 +100,7 @@ class MultipleVhostsTestFedora(util.ApacheTest): def test_get_parser(self): self.assertIsInstance(self.config.parser, override_fedora.FedoraParser) - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_opportunistic_httpd_runtime_parsing(self, mock_get): define_val = ( 'Define: TEST1\n' @@ -135,7 +134,7 @@ class MultipleVhostsTestFedora(util.ApacheTest): self.assertTrue("TEST2" in self.config.parser.variables.keys()) self.assertTrue("mod_another.c" in self.config.parser.modules) - @mock.patch("certbot_apache.configurator.util.run_script") + @mock.patch("certbot_apache._internal.configurator.util.run_script") def test_get_version(self, mock_run_script): mock_run_script.return_value = ('', None) self.assertRaises(errors.PluginError, self.config.get_version) @@ -156,7 +155,7 @@ class MultipleVhostsTestFedora(util.ApacheTest): raise Exception("Missed: %s" % vhost) # pragma: no cover self.assertEqual(found, 2) - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_get_sysconfig_vars(self, mock_cfg): """Make sure we read the sysconfig OPTIONS variable correctly""" # Return nothing for the process calls @@ -177,13 +176,13 @@ class MultipleVhostsTestFedora(util.ApacheTest): self.assertTrue("MOCK_NOSEP" in self.config.parser.variables.keys()) self.assertEqual("NOSEP_VAL", self.config.parser.variables["NOSEP_TWO"]) - @mock.patch("certbot_apache.configurator.util.run_script") + @mock.patch("certbot_apache._internal.configurator.util.run_script") def test_alt_restart_works(self, mock_run_script): mock_run_script.side_effect = [None, errors.SubprocessError, None] self.config.restart() self.assertEqual(mock_run_script.call_count, 3) - @mock.patch("certbot_apache.configurator.util.run_script") + @mock.patch("certbot_apache._internal.configurator.util.run_script") def test_alt_restart_errors(self, mock_run_script): mock_run_script.side_effect = [None, errors.SubprocessError, diff --git a/certbot-apache/certbot_apache/tests/gentoo_test.py b/certbot-apache/tests/gentoo_test.py similarity index 86% rename from certbot-apache/certbot_apache/tests/gentoo_test.py rename to certbot-apache/tests/gentoo_test.py index d0d3ba0dd..90a163fd3 100644 --- a/certbot-apache/certbot_apache/tests/gentoo_test.py +++ b/certbot-apache/tests/gentoo_test.py @@ -1,4 +1,4 @@ -"""Test for certbot_apache.configurator for Gentoo overrides""" +"""Test for certbot_apache._internal.configurator for Gentoo overrides""" import unittest import mock @@ -6,10 +6,9 @@ import mock from certbot import errors from certbot.compat import filesystem from certbot.compat import os - -from certbot_apache import obj -from certbot_apache import override_gentoo -from certbot_apache.tests import util +from certbot_apache._internal import obj +from certbot_apache._internal import override_gentoo +import util def get_vh_truth(temp_dir, config_name): @@ -52,7 +51,8 @@ class MultipleVhostsTestGentoo(util.ApacheTest): config_root=config_root, vhost_root=vhost_root) - with mock.patch("certbot_apache.override_gentoo.GentooParser.update_runtime_variables"): + # pylint: disable=line-too-long + with mock.patch("certbot_apache._internal.override_gentoo.GentooParser.update_runtime_variables"): self.config = util.get_apache_configurator( self.config_path, self.vhost_path, self.config_dir, self.work_dir, os_info="gentoo") @@ -85,17 +85,17 @@ class MultipleVhostsTestGentoo(util.ApacheTest): self.config.parser.apacheconfig_filep = filesystem.realpath( os.path.join(self.config.parser.root, "../conf.d/apache2")) self.config.parser.variables = {} - with mock.patch("certbot_apache.override_gentoo.GentooParser.update_modules"): + with mock.patch("certbot_apache._internal.override_gentoo.GentooParser.update_modules"): self.config.parser.update_runtime_variables() for define in defines: self.assertTrue(define in self.config.parser.variables.keys()) - @mock.patch("certbot_apache.parser.ApacheParser.parse_from_subprocess") + @mock.patch("certbot_apache._internal.parser.ApacheParser.parse_from_subprocess") def test_no_binary_configdump(self, mock_subprocess): """Make sure we don't call binary dumps other than modules from Apache as this is not supported in Gentoo currently""" - with mock.patch("certbot_apache.override_gentoo.GentooParser.update_modules"): + with mock.patch("certbot_apache._internal.override_gentoo.GentooParser.update_modules"): self.config.parser.update_runtime_variables() self.config.parser.reset_modules() self.assertFalse(mock_subprocess.called) @@ -104,7 +104,7 @@ class MultipleVhostsTestGentoo(util.ApacheTest): self.config.parser.reset_modules() self.assertTrue(mock_subprocess.called) - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_opportunistic_httpd_runtime_parsing(self, mock_get): mod_val = ( 'Loaded Modules:\n' @@ -128,7 +128,7 @@ class MultipleVhostsTestGentoo(util.ApacheTest): self.assertEqual(len(self.config.parser.modules), 4) self.assertTrue("mod_another.c" in self.config.parser.modules) - @mock.patch("certbot_apache.configurator.util.run_script") + @mock.patch("certbot_apache._internal.configurator.util.run_script") def test_alt_restart_works(self, mock_run_script): mock_run_script.side_effect = [None, errors.SubprocessError, None] self.config.restart() diff --git a/certbot-apache/certbot_apache/tests/http_01_test.py b/certbot-apache/tests/http_01_test.py similarity index 95% rename from certbot-apache/certbot_apache/tests/http_01_test.py rename to certbot-apache/tests/http_01_test.py index fade85b3a..643a6bdd5 100644 --- a/certbot-apache/certbot_apache/tests/http_01_test.py +++ b/certbot-apache/tests/http_01_test.py @@ -1,25 +1,23 @@ -"""Test for certbot_apache.http_01.""" +"""Test for certbot_apache._internal.http_01.""" import unittest + import mock from acme import challenges from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - from certbot import achallenges from certbot import errors from certbot.compat import filesystem from certbot.compat import os from certbot.tests import acme_util - -from certbot_apache.parser import get_aug_path -from certbot_apache.tests import util - +from certbot_apache._internal.parser import get_aug_path +import util NUM_ACHALLS = 3 class ApacheHttp01Test(util.ApacheTest): - """Test for certbot_apache.http_01.ApacheHttp01.""" + """Test for certbot_apache._internal.http_01.ApacheHttp01.""" def setUp(self, *args, **kwargs): # pylint: disable=arguments-differ super(ApacheHttp01Test, self).setUp(*args, **kwargs) @@ -45,13 +43,13 @@ class ApacheHttp01Test(util.ApacheTest): self.config.parser.modules.add("mod_{0}.c".format(mod)) self.config.parser.modules.add(mod + "_module") - from certbot_apache.http_01 import ApacheHttp01 + from certbot_apache._internal.http_01 import ApacheHttp01 self.http = ApacheHttp01(self.config) def test_empty_perform(self): self.assertFalse(self.http.perform()) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.enable_mod") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.enable_mod") def test_enable_modules_apache_2_2(self, mock_enmod): self.config.version = (2, 2) self.config.parser.modules.remove("authz_host_module") @@ -60,7 +58,7 @@ class ApacheHttp01Test(util.ApacheTest): enmod_calls = self.common_enable_modules_test(mock_enmod) self.assertEqual(enmod_calls[0][0][0], "authz_host") - @mock.patch("certbot_apache.configurator.ApacheConfigurator.enable_mod") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.enable_mod") def test_enable_modules_apache_2_4(self, mock_enmod): self.config.parser.modules.remove("authz_core_module") self.config.parser.modules.remove("mod_authz_core.c") diff --git a/certbot-apache/certbot_apache/tests/obj_test.py b/certbot-apache/tests/obj_test.py similarity index 89% rename from certbot-apache/certbot_apache/tests/obj_test.py rename to certbot-apache/tests/obj_test.py index 10dba18bc..1761b9c94 100644 --- a/certbot-apache/certbot_apache/tests/obj_test.py +++ b/certbot-apache/tests/obj_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_apache.obj.""" +"""Tests for certbot_apache._internal.obj.""" import unittest @@ -6,8 +6,8 @@ class VirtualHostTest(unittest.TestCase): """Test the VirtualHost class.""" def setUp(self): - from certbot_apache.obj import Addr - from certbot_apache.obj import VirtualHost + from certbot_apache._internal.obj import Addr + from certbot_apache._internal.obj import VirtualHost self.addr1 = Addr.fromstring("127.0.0.1") self.addr2 = Addr.fromstring("127.0.0.1:443") @@ -23,7 +23,8 @@ class VirtualHostTest(unittest.TestCase): "fp", "vhp", set([self.addr2]), False, False, "localhost") def test_repr(self): - self.assertEqual(repr(self.addr2), "certbot_apache.obj.Addr(('127.0.0.1', '443'))") + self.assertEqual(repr(self.addr2), + "certbot_apache._internal.obj.Addr(('127.0.0.1', '443'))") def test_eq(self): self.assertTrue(self.vhost1b == self.vhost1) @@ -36,8 +37,8 @@ class VirtualHostTest(unittest.TestCase): self.assertFalse(self.vhost1 != self.vhost1b) def test_conflicts(self): - from certbot_apache.obj import Addr - from certbot_apache.obj import VirtualHost + from certbot_apache._internal.obj import Addr + from certbot_apache._internal.obj import VirtualHost complex_vh = VirtualHost( "fp", "vhp", @@ -54,7 +55,7 @@ class VirtualHostTest(unittest.TestCase): self.addr_default])) def test_same_server(self): - from certbot_apache.obj import VirtualHost + from certbot_apache._internal.obj import VirtualHost no_name1 = VirtualHost( "fp", "vhp", set([self.addr1]), False, False, None) no_name2 = VirtualHost( @@ -77,7 +78,7 @@ class VirtualHostTest(unittest.TestCase): class AddrTest(unittest.TestCase): """Test obj.Addr.""" def setUp(self): - from certbot_apache.obj import Addr + from certbot_apache._internal.obj import Addr self.addr = Addr.fromstring("*:443") self.addr1 = Addr.fromstring("127.0.0.1") @@ -92,7 +93,7 @@ class AddrTest(unittest.TestCase): self.assertTrue(self.addr2.is_wildcard()) def test_get_sni_addr(self): - from certbot_apache.obj import Addr + from certbot_apache._internal.obj import Addr self.assertEqual( self.addr.get_sni_addr("443"), Addr.fromstring("*:443")) self.assertEqual( diff --git a/certbot-apache/certbot_apache/tests/parser_test.py b/certbot-apache/tests/parser_test.py similarity index 86% rename from certbot-apache/certbot_apache/tests/parser_test.py rename to certbot-apache/tests/parser_test.py index 27d66f680..b334ce52e 100644 --- a/certbot-apache/certbot_apache/tests/parser_test.py +++ b/certbot-apache/tests/parser_test.py @@ -1,5 +1,4 @@ -# pylint: disable=too-many-public-methods -"""Tests for certbot_apache.parser.""" +"""Tests for certbot_apache._internal.parser.""" import shutil import unittest @@ -7,8 +6,7 @@ import mock from certbot import errors from certbot.compat import os - -from certbot_apache.tests import util +import util class BasicParserTest(util.ParserTest): @@ -114,7 +112,7 @@ class BasicParserTest(util.ParserTest): Path must be valid before attempting to add to augeas """ - from certbot_apache.parser import get_aug_path + from certbot_apache._internal.parser import get_aug_path # This makes sure that find_dir will work self.parser.modules.add("mod_ssl.c") @@ -128,7 +126,7 @@ class BasicParserTest(util.ParserTest): self.assertTrue("IfModule" in matches[0]) def test_add_dir_to_ifmodssl_multiple(self): - from certbot_apache.parser import get_aug_path + from certbot_apache._internal.parser import get_aug_path # This makes sure that find_dir will work self.parser.modules.add("mod_ssl.c") @@ -142,11 +140,11 @@ class BasicParserTest(util.ParserTest): self.assertTrue("IfModule" in matches[0]) def test_get_aug_path(self): - from certbot_apache.parser import get_aug_path + from certbot_apache._internal.parser import get_aug_path self.assertEqual("/files/etc/apache", get_aug_path("/etc/apache")) def test_set_locations(self): - with mock.patch("certbot_apache.parser.os.path") as mock_path: + with mock.patch("certbot_apache._internal.parser.os.path") as mock_path: mock_path.isfile.side_effect = [False, False] @@ -156,18 +154,18 @@ class BasicParserTest(util.ParserTest): self.assertEqual(results["default"], results["listen"]) self.assertEqual(results["default"], results["name"]) - @mock.patch("certbot_apache.parser.ApacheParser.find_dir") - @mock.patch("certbot_apache.parser.ApacheParser.get_arg") + @mock.patch("certbot_apache._internal.parser.ApacheParser.find_dir") + @mock.patch("certbot_apache._internal.parser.ApacheParser.get_arg") def test_parse_modules_bad_syntax(self, mock_arg, mock_find): mock_find.return_value = ["1", "2", "3", "4", "5", "6", "7", "8"] mock_arg.return_value = None - with mock.patch("certbot_apache.parser.logger") as mock_logger: + with mock.patch("certbot_apache._internal.parser.logger") as mock_logger: self.parser.parse_modules() # Make sure that we got None return value and logged the file self.assertTrue(mock_logger.debug.called) - @mock.patch("certbot_apache.parser.ApacheParser.find_dir") - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.parser.ApacheParser.find_dir") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_update_runtime_variables(self, mock_cfg, _): define_val = ( 'ServerRoot: "/etc/apache2"\n' @@ -264,7 +262,7 @@ class BasicParserTest(util.ParserTest): self.parser.modules = set() with mock.patch( - "certbot_apache.parser.ApacheParser.parse_file") as mock_parse: + "certbot_apache._internal.parser.ApacheParser.parse_file") as mock_parse: self.parser.update_runtime_variables() self.assertEqual(self.parser.variables, expected_vars) self.assertEqual(len(self.parser.modules), 58) @@ -272,8 +270,8 @@ class BasicParserTest(util.ParserTest): # Make sure we tried to include them all. self.assertEqual(mock_parse.call_count, 25) - @mock.patch("certbot_apache.parser.ApacheParser.find_dir") - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.parser.ApacheParser.find_dir") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_update_runtime_variables_alt_values(self, mock_cfg, _): inc_val = ( 'Included configuration files:\n' @@ -287,7 +285,7 @@ class BasicParserTest(util.ParserTest): self.parser.modules = set() with mock.patch( - "certbot_apache.parser.ApacheParser.parse_file") as mock_parse: + "certbot_apache._internal.parser.ApacheParser.parse_file") as mock_parse: self.parser.update_runtime_variables() # No matching modules should have been found self.assertEqual(len(self.parser.modules), 0) @@ -295,7 +293,7 @@ class BasicParserTest(util.ParserTest): # path derived from root configuration Include statements self.assertEqual(mock_parse.call_count, 1) - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_update_runtime_vars_bad_output(self, mock_cfg): mock_cfg.return_value = "Define: TLS=443=24" self.parser.update_runtime_variables() @@ -304,8 +302,8 @@ class BasicParserTest(util.ParserTest): self.assertRaises( errors.PluginError, self.parser.update_runtime_variables) - @mock.patch("certbot_apache.configurator.ApacheConfigurator.option") - @mock.patch("certbot_apache.parser.subprocess.Popen") + @mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.option") + @mock.patch("certbot_apache._internal.parser.subprocess.Popen") def test_update_runtime_vars_bad_ctl(self, mock_popen, mock_opt): mock_popen.side_effect = OSError mock_opt.return_value = "nonexistent" @@ -313,7 +311,7 @@ class BasicParserTest(util.ParserTest): errors.MisconfigurationError, self.parser.update_runtime_variables) - @mock.patch("certbot_apache.parser.subprocess.Popen") + @mock.patch("certbot_apache._internal.parser.subprocess.Popen") def test_update_runtime_vars_bad_exit(self, mock_popen): mock_popen().communicate.return_value = ("", "") mock_popen.returncode = -1 @@ -322,7 +320,7 @@ class BasicParserTest(util.ParserTest): self.parser.update_runtime_variables) def test_add_comment(self): - from certbot_apache.parser import get_aug_path + from certbot_apache._internal.parser import get_aug_path self.parser.add_comment(get_aug_path(self.parser.loc["name"]), "123456") comm = self.parser.find_comments("123456") self.assertEqual(len(comm), 1) @@ -338,9 +336,9 @@ class ParserInitTest(util.ApacheTest): shutil.rmtree(self.config_dir) shutil.rmtree(self.work_dir) - @mock.patch("certbot_apache.parser.ApacheParser.init_augeas") + @mock.patch("certbot_apache._internal.parser.ApacheParser.init_augeas") def test_prepare_no_augeas(self, mock_init_augeas): - from certbot_apache.parser import ApacheParser + from certbot_apache._internal.parser import ApacheParser mock_init_augeas.side_effect = errors.NoInstallationError self.config.config_test = mock.Mock() self.assertRaises( @@ -349,17 +347,17 @@ class ParserInitTest(util.ApacheTest): version=(2, 4, 22), configurator=self.config) def test_init_old_aug(self): - from certbot_apache.parser import ApacheParser - with mock.patch("certbot_apache.parser.ApacheParser.check_aug_version") as mock_c: + from certbot_apache._internal.parser import ApacheParser + with mock.patch("certbot_apache._internal.parser.ApacheParser.check_aug_version") as mock_c: mock_c.return_value = False self.assertRaises( errors.NotSupportedError, ApacheParser, os.path.relpath(self.config_path), "/dummy/vhostpath", version=(2, 4, 22), configurator=self.config) - @mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg") + @mock.patch("certbot_apache._internal.parser.ApacheParser._get_runtime_cfg") def test_unparseable(self, mock_cfg): - from certbot_apache.parser import ApacheParser + from certbot_apache._internal.parser import ApacheParser mock_cfg.return_value = ('Define: TEST') self.assertRaises( errors.PluginError, @@ -367,9 +365,9 @@ class ParserInitTest(util.ApacheTest): "/dummy/vhostpath", version=(2, 2, 22), configurator=self.config) def test_root_normalized(self): - from certbot_apache.parser import ApacheParser + from certbot_apache._internal.parser import ApacheParser - with mock.patch("certbot_apache.parser.ApacheParser." + with mock.patch("certbot_apache._internal.parser.ApacheParser." "update_runtime_variables"): path = os.path.join( self.temp_dir, @@ -380,8 +378,8 @@ class ParserInitTest(util.ApacheTest): self.assertEqual(parser.root, self.config_path) def test_root_absolute(self): - from certbot_apache.parser import ApacheParser - with mock.patch("certbot_apache.parser.ApacheParser." + from certbot_apache._internal.parser import ApacheParser + with mock.patch("certbot_apache._internal.parser.ApacheParser." "update_runtime_variables"): parser = ApacheParser( os.path.relpath(self.config_path), @@ -390,8 +388,8 @@ class ParserInitTest(util.ApacheTest): self.assertEqual(parser.root, self.config_path) def test_root_no_trailing_slash(self): - from certbot_apache.parser import ApacheParser - with mock.patch("certbot_apache.parser.ApacheParser." + from certbot_apache._internal.parser import ApacheParser + with mock.patch("certbot_apache._internal.parser.ApacheParser." "update_runtime_variables"): parser = ApacheParser( self.config_path + os.path.sep, diff --git a/certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/README b/certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf.d/README similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/README rename to certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf.d/README diff --git a/certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/ssl.conf b/certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf.d/ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/ssl.conf rename to certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf.d/ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/test.example.com.conf b/certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf.d/test.example.com.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/test.example.com.conf rename to certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf.d/test.example.com.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/welcome.conf b/certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf.d/welcome.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf.d/welcome.conf rename to certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf.d/welcome.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf/httpd.conf b/certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf/httpd.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos6_apache/apache/httpd/conf/httpd.conf rename to certbot-apache/tests/testdata/centos6_apache/apache/httpd/conf/httpd.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/README b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/README similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/README rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/README diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/autoindex.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/autoindex.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/autoindex.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/autoindex.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/centos.example.com.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/centos.example.com.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/centos.example.com.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/centos.example.com.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/ssl.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/ssl.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/userdir.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/userdir.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/userdir.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/userdir.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/welcome.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/welcome.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.d/welcome.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.d/welcome.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-base.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-base.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-base.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-base.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-dav.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-dav.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-dav.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-dav.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-lua.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-lua.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-lua.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-lua.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-mpm.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-mpm.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-mpm.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-mpm.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-proxy.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-proxy.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-proxy.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-proxy.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-ssl.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-ssl.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-systemd.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-systemd.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-systemd.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/00-systemd.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/01-cgi.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/01-cgi.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/01-cgi.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf.modules.d/01-cgi.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf/httpd.conf b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf/httpd.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf/httpd.conf rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf/httpd.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf/magic b/certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf/magic similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/httpd/conf/magic rename to certbot-apache/tests/testdata/centos7_apache/apache/httpd/conf/magic diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/sites b/certbot-apache/tests/testdata/centos7_apache/apache/sites similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/sites rename to certbot-apache/tests/testdata/centos7_apache/apache/sites diff --git a/certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/sysconfig/httpd b/certbot-apache/tests/testdata/centos7_apache/apache/sysconfig/httpd similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/centos7_apache/apache/sysconfig/httpd rename to certbot-apache/tests/testdata/centos7_apache/apache/sysconfig/httpd diff --git a/certbot-apache/certbot_apache/tests/testdata/complex_parsing/apache2.conf b/certbot-apache/tests/testdata/complex_parsing/apache2.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/complex_parsing/apache2.conf rename to certbot-apache/tests/testdata/complex_parsing/apache2.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/complex_parsing/conf-enabled/dummy.conf b/certbot-apache/tests/testdata/complex_parsing/conf-enabled/dummy.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/complex_parsing/conf-enabled/dummy.conf rename to certbot-apache/tests/testdata/complex_parsing/conf-enabled/dummy.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/complex_parsing/test_fnmatch.conf b/certbot-apache/tests/testdata/complex_parsing/test_fnmatch.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/complex_parsing/test_fnmatch.conf rename to certbot-apache/tests/testdata/complex_parsing/test_fnmatch.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/complex_parsing/test_variables.conf b/certbot-apache/tests/testdata/complex_parsing/test_variables.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/complex_parsing/test_variables.conf rename to certbot-apache/tests/testdata/complex_parsing/test_variables.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/apache2.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/apache2.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/apache2.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/apache2.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/bad_conf_file.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/bad_conf_file.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/bad_conf_file.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/bad_conf_file.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/other-vhosts-access-log.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/other-vhosts-access-log.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/other-vhosts-access-log.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/other-vhosts-access-log.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/security.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/security.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/security.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/security.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/serve-cgi-bin.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/serve-cgi-bin.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/serve-cgi-bin.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-available/serve-cgi-bin.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/other-vhosts-access-log.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/other-vhosts-access-log.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/other-vhosts-access-log.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/other-vhosts-access-log.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/security.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/security.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/security.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/security.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/serve-cgi-bin.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/serve-cgi-bin.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/serve-cgi-bin.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/conf-enabled/serve-cgi-bin.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/envvars b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/envvars similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/envvars rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/envvars diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/authz_svn.load b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/authz_svn.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/authz_svn.load rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/authz_svn.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav.load b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav.load rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav_svn.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav_svn.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav_svn.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav_svn.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav_svn.load b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav_svn.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav_svn.load rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/dav_svn.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/rewrite.load b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/rewrite.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/rewrite.load rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/rewrite.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/ssl.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/ssl.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/ssl.load b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/ssl.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/ssl.load rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-available/ssl.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/authz_svn.load b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/authz_svn.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/authz_svn.load rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/authz_svn.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav.load b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav.load rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav_svn.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav_svn.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav_svn.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav_svn.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav_svn.load b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav_svn.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav_svn.load rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/mods-enabled/dav_svn.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/ports.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/ports.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/ports.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/ports.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/another_wildcard.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/another_wildcard.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/another_wildcard.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/another_wildcard.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/old-and-default.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/old-and-default.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/old-and-default.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/old-and-default.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/wildcard.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/wildcard.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/wildcard.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-available/wildcard.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/another_wildcard.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/another_wildcard.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/another_wildcard.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/another_wildcard.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/old-and-default.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/old-and-default.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/old-and-default.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/old-and-default.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/wildcard.conf b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/wildcard.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/wildcard.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/apache2/sites-enabled/wildcard.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/sites b/certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/sites similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/augeas_vhosts/sites rename to certbot-apache/tests/testdata/debian_apache_2_4/augeas_vhosts/sites diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/apache2.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/apache2.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/apache2.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/apache2.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/other-vhosts-access-log.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/other-vhosts-access-log.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/other-vhosts-access-log.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/other-vhosts-access-log.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/security.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/security.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/security.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/security.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/serve-cgi-bin.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/serve-cgi-bin.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/serve-cgi-bin.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-available/serve-cgi-bin.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/other-vhosts-access-log.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/other-vhosts-access-log.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/other-vhosts-access-log.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/other-vhosts-access-log.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/security.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/security.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/security.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/security.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/serve-cgi-bin.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/serve-cgi-bin.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/serve-cgi-bin.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/conf-enabled/serve-cgi-bin.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/envvars b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/envvars similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/envvars rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/envvars diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/mods-available/ssl.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/mods-available/ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/mods-available/ssl.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/mods-available/ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/mods-available/ssl.load b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/mods-available/ssl.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/mods-available/ssl.load rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/mods-available/ssl.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/ports.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/ports.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/ports.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/ports.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-available/000-default.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-available/000-default.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-available/000-default.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-available/000-default.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-available/default-ssl.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-available/default-ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-available/default-ssl.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-available/default-ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-enabled/000-default.conf b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-enabled/000-default.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-enabled/000-default.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/apache2/sites-enabled/000-default.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/sites b/certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/sites similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/default_vhost/sites rename to certbot-apache/tests/testdata/debian_apache_2_4/default_vhost/sites diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/apache2.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/apache2.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/apache2.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/apache2.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/envvars b/certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/envvars similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/envvars rename to certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/envvars diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/ports.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/ports.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/ports.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/ports.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-available/default.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-available/default.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-available/default.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-available/default.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-available/multi-vhost.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-available/multi-vhost.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-available/multi-vhost.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-available/multi-vhost.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-enabled/default.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-enabled/default.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-enabled/default.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-enabled/default.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-enabled/multi-vhost.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-enabled/multi-vhost.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-enabled/multi-vhost.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multi_vhosts/apache2/sites-enabled/multi-vhost.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/apache2.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/apache2.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/apache2.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/apache2.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/bad_conf_file.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/bad_conf_file.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/bad_conf_file.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/bad_conf_file.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/other-vhosts-access-log.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/other-vhosts-access-log.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/other-vhosts-access-log.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/other-vhosts-access-log.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/security.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/security.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/security.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/security.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/serve-cgi-bin.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/serve-cgi-bin.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/serve-cgi-bin.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-available/serve-cgi-bin.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/other-vhosts-access-log.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/other-vhosts-access-log.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/other-vhosts-access-log.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/other-vhosts-access-log.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/security.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/security.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/security.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/security.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/serve-cgi-bin.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/serve-cgi-bin.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/serve-cgi-bin.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/conf-enabled/serve-cgi-bin.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/envvars b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/envvars similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/envvars rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/envvars diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/authz_svn.load b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/authz_svn.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/authz_svn.load rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/authz_svn.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav.load b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav.load rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav_svn.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav_svn.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav_svn.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav_svn.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav_svn.load b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav_svn.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav_svn.load rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/dav_svn.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/rewrite.load b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/rewrite.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/rewrite.load rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/rewrite.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/ssl.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/ssl.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/ssl.load b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/ssl.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/ssl.load rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-available/ssl.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/authz_svn.load b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/authz_svn.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/authz_svn.load rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/authz_svn.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav.load b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav.load rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav_svn.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav_svn.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav_svn.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav_svn.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav_svn.load b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav_svn.load similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav_svn.load rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/mods-enabled/dav_svn.load diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/ports.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/ports.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/ports.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/ports.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/000-default.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/000-default.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/000-default.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/000-default.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/certbot.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/certbot.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/certbot.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/certbot.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/default-ssl-port-only.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/default-ssl-port-only.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/default-ssl-port-only.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/default-ssl-port-only.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/default-ssl.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/default-ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/default-ssl.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/default-ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/duplicatehttp.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/duplicatehttp.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/duplicatehttp.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/duplicatehttp.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/duplicatehttps.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/duplicatehttps.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/duplicatehttps.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/duplicatehttps.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/encryption-example.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/encryption-example.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/encryption-example.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/encryption-example.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/mod_macro-example.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/mod_macro-example.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/mod_macro-example.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/mod_macro-example.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/ocsp-ssl.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/ocsp-ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/ocsp-ssl.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/ocsp-ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/wildcard.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/wildcard.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/wildcard.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-available/wildcard.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/000-default.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/000-default.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/000-default.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/000-default.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/certbot.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/certbot.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/certbot.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/certbot.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/default-ssl-port-only.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/default-ssl-port-only.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/default-ssl-port-only.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/default-ssl-port-only.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/default-ssl.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/default-ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/default-ssl.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/default-ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/duplicatehttp.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/duplicatehttp.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/duplicatehttp.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/duplicatehttp.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/duplicatehttps.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/duplicatehttps.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/duplicatehttps.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/duplicatehttps.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/encryption-example.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/encryption-example.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/encryption-example.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/encryption-example.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/mod_macro-example.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/mod_macro-example.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/mod_macro-example.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/mod_macro-example.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/non-symlink.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/non-symlink.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/non-symlink.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/non-symlink.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/ocsp-ssl.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/ocsp-ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/ocsp-ssl.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/ocsp-ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/wildcard.conf b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/wildcard.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/wildcard.conf rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/apache2/sites-enabled/wildcard.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/sites b/certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/sites similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/debian_apache_2_4/multiple_vhosts/sites rename to certbot-apache/tests/testdata/debian_apache_2_4/multiple_vhosts/sites diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/httpd.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/httpd.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/httpd.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/httpd.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/magic b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/magic similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/magic rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/magic diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_default_settings.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_default_settings.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_default_settings.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_default_settings.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_error_documents.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_error_documents.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_error_documents.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_error_documents.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_languages.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_languages.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_languages.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_languages.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_autoindex.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_autoindex.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_autoindex.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_autoindex.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_info.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_info.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_info.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_info.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_log_config.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_log_config.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_log_config.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_log_config.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_mime.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_mime.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_mime.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_mime.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_status.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_status.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_status.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_status.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_userdir.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_userdir.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_userdir.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mod_userdir.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mpm.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mpm.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mpm.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/00_mpm.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/10_mod_mem_cache.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/10_mod_mem_cache.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/10_mod_mem_cache.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/10_mod_mem_cache.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/40_mod_ssl.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/40_mod_ssl.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/40_mod_ssl.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/40_mod_ssl.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/41_mod_http2.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/41_mod_http2.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/41_mod_http2.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/41_mod_http2.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/45_mod_dav.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/45_mod_dav.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/45_mod_dav.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/45_mod_dav.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/46_mod_ldap.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/46_mod_ldap.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/46_mod_ldap.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/modules.d/46_mod_ldap.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/00_default_ssl_vhost.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/00_default_ssl_vhost.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/00_default_ssl_vhost.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/00_default_ssl_vhost.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/00_default_vhost.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/00_default_vhost.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/00_default_vhost.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/00_default_vhost.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/default_vhost.include b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/default_vhost.include similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/default_vhost.include rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/default_vhost.include diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/gentoo.example.com.conf b/certbot-apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/gentoo.example.com.conf similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/gentoo.example.com.conf rename to certbot-apache/tests/testdata/gentoo_apache/apache/apache2/vhosts.d/gentoo.example.com.conf diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/conf.d/apache2 b/certbot-apache/tests/testdata/gentoo_apache/apache/conf.d/apache2 similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/conf.d/apache2 rename to certbot-apache/tests/testdata/gentoo_apache/apache/conf.d/apache2 diff --git a/certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/sites b/certbot-apache/tests/testdata/gentoo_apache/apache/sites similarity index 100% rename from certbot-apache/certbot_apache/tests/testdata/gentoo_apache/apache/sites rename to certbot-apache/tests/testdata/gentoo_apache/apache/sites diff --git a/certbot-apache/certbot_apache/tests/util.py b/certbot-apache/tests/util.py similarity index 94% rename from certbot-apache/certbot_apache/tests/util.py rename to certbot-apache/tests/util.py index 8e3de04be..57b20dc9d 100644 --- a/certbot-apache/certbot_apache/tests/util.py +++ b/certbot-apache/tests/util.py @@ -12,13 +12,12 @@ from certbot.compat import os from certbot.display import util as display_util from certbot.plugins import common from certbot.tests import util as test_util - -from certbot_apache import configurator -from certbot_apache import entrypoint -from certbot_apache import obj +from certbot_apache._internal import configurator +from certbot_apache._internal import entrypoint +from certbot_apache._internal import obj -class ApacheTest(unittest.TestCase): # pylint: disable=too-few-public-methods +class ApacheTest(unittest.TestCase): def setUp(self, test_dir="debian_apache_2_4/multiple_vhosts", config_root="debian_apache_2_4/multiple_vhosts/apache2", @@ -28,7 +27,7 @@ class ApacheTest(unittest.TestCase): # pylint: disable=too-few-public-methods self.temp_dir, self.config_dir, self.work_dir = common.dir_setup( test_dir=test_dir, - pkg="certbot_apache.tests") + pkg=__name__) self.config_path = os.path.join(self.temp_dir, config_root) self.vhost_path = os.path.join(self.temp_dir, vhost_root) @@ -72,16 +71,16 @@ class ParserTest(ApacheTest): zope.component.provideUtility(display_util.FileDisplay(sys.stdout, False)) - from certbot_apache.parser import ApacheParser + from certbot_apache._internal.parser import ApacheParser self.aug = augeas.Augeas( flags=augeas.Augeas.NONE | augeas.Augeas.NO_MODL_AUTOLOAD) - with mock.patch("certbot_apache.parser.ApacheParser." + with mock.patch("certbot_apache._internal.parser.ApacheParser." "update_runtime_variables"): self.parser = ApacheParser( self.config_path, self.vhost_path, configurator=self.config) -def get_apache_configurator( # pylint: disable=too-many-arguments, too-many-locals +def get_apache_configurator( config_path, vhost_path, config_dir, work_dir, version=(2, 4, 7), os_info="generic", @@ -105,11 +104,11 @@ def get_apache_configurator( # pylint: disable=too-many-arguments, too-many-loc in_progress_dir=os.path.join(backups, "IN_PROGRESS"), work_dir=work_dir) - with mock.patch("certbot_apache.configurator.util.run_script"): - with mock.patch("certbot_apache.configurator.util." + with mock.patch("certbot_apache._internal.configurator.util.run_script"): + with mock.patch("certbot_apache._internal.configurator.util." "exe_exists") as mock_exe_exists: mock_exe_exists.return_value = True - with mock.patch("certbot_apache.parser.ApacheParser." + with mock.patch("certbot_apache._internal.parser.ApacheParser." "update_runtime_variables"): try: config_class = entrypoint.OVERRIDE_CLASSES[os_info] diff --git a/certbot-auto b/certbot-auto index 9f3d2af08..2d3f4cfef 100755 --- a/certbot-auto +++ b/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="0.40.1" +LE_AUTO_VERSION="1.1.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 @@ -1145,63 +1276,70 @@ if [ "$1" = "--le-auto-phase2" ]; then # ``` ConfigArgParse==0.14.0 \ --hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91 -asn1crypto==0.24.0 \ - --hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \ - --hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49 -certifi==2019.6.16 \ - --hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \ - --hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695 -cffi==1.12.3 \ - --hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \ - --hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \ - --hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \ - --hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \ - --hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \ - --hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \ - --hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \ - --hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \ - --hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \ - --hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \ - --hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \ - --hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \ - --hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \ - --hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \ - --hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \ - --hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \ - --hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \ - --hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \ - --hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \ - --hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \ - --hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \ - --hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \ - --hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \ - --hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \ - --hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \ - --hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \ - --hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \ - --hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201 +certifi==2019.9.11 \ + --hash=sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50 \ + --hash=sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef +cffi==1.13.2 \ + --hash=sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42 \ + --hash=sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04 \ + --hash=sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5 \ + --hash=sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54 \ + --hash=sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba \ + --hash=sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57 \ + --hash=sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396 \ + --hash=sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12 \ + --hash=sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97 \ + --hash=sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43 \ + --hash=sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db \ + --hash=sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3 \ + --hash=sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b \ + --hash=sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579 \ + --hash=sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346 \ + --hash=sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159 \ + --hash=sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652 \ + --hash=sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e \ + --hash=sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a \ + --hash=sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506 \ + --hash=sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f \ + --hash=sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d \ + --hash=sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c \ + --hash=sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20 \ + --hash=sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858 \ + --hash=sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc \ + --hash=sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a \ + --hash=sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3 \ + --hash=sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e \ + --hash=sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410 \ + --hash=sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25 \ + --hash=sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b \ + --hash=sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d chardet==3.0.4 \ --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \ --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 -cryptography==2.7 \ - --hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \ - --hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \ - --hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \ - --hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \ - --hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \ - --hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \ - --hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \ - --hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \ - --hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \ - --hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \ - --hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \ - --hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \ - --hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \ - --hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \ - --hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \ - --hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d +cryptography==2.8 \ + --hash=sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c \ + --hash=sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595 \ + --hash=sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad \ + --hash=sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651 \ + --hash=sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2 \ + --hash=sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff \ + --hash=sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d \ + --hash=sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42 \ + --hash=sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d \ + --hash=sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e \ + --hash=sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912 \ + --hash=sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793 \ + --hash=sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13 \ + --hash=sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7 \ + --hash=sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0 \ + --hash=sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879 \ + --hash=sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f \ + --hash=sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9 \ + --hash=sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2 \ + --hash=sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf \ + --hash=sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8 distro==1.4.0 \ --hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \ --hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4 @@ -1213,14 +1351,14 @@ enum34==1.1.6 \ funcsigs==1.0.2 \ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \ --hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50 -future==0.17.1 \ - --hash=sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8 +future==0.18.2 \ + --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d idna==2.8 \ --hash=sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407 \ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c -ipaddress==1.0.22 \ - --hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \ - --hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c +ipaddress==1.0.23 \ + --hash=sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc \ + --hash=sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2 josepy==1.2.0 \ --hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \ --hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3 @@ -1230,9 +1368,9 @@ mock==1.3.0 \ parsedatetime==2.4 \ --hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \ --hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094 -pbr==5.4.2 \ - --hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \ - --hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf +pbr==5.4.3 \ + --hash=sha256:2c8e420cd4ed4cec4e7999ee47409e876af575d4c35a45840d59e8b5f3155ab8 \ + --hash=sha256:b32c8ccaac7b1a20c0ce00ce317642e6cf231cf038f9875e0280e28af5bf7ac9 pyOpenSSL==19.0.0 \ --hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \ --hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6 @@ -1241,29 +1379,28 @@ pyRFC3339==1.1 \ --hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a pycparser==2.19 \ --hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3 -pyparsing==2.4.2 \ - --hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \ - --hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4 +pyparsing==2.4.5 \ + --hash=sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f \ + --hash=sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a python-augeas==0.5.0 \ --hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2 -pytz==2019.2 \ - --hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \ - --hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7 +pytz==2019.3 \ + --hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \ + --hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be requests==2.21.0 \ --hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \ --hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b requests-toolbelt==0.9.1 \ --hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \ --hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0 -six==1.12.0 \ - --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \ - --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 +six==1.13.0 \ + --hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \ + --hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66 urllib3==1.24.3 \ --hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \ --hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb -zope.component==4.5 \ - --hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \ - --hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4 +zope.component==4.6 \ + --hash=sha256:ec2afc5bbe611dcace98bb39822c122d44743d635dafc7315b9aef25097db9e6 zope.deferredimport==4.3.1 \ --hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \ --hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a @@ -1314,18 +1451,46 @@ zope.interface==4.6.0 \ --hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \ --hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \ --hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317 -zope.proxy==4.3.2 \ - --hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \ - --hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \ - --hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \ - --hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \ - --hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \ - --hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \ - --hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \ - --hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \ - --hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \ - --hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \ - --hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366 +zope.proxy==4.3.3 \ + --hash=sha256:04646ac04ffa9c8e32fb2b5c3cd42995b2548ea14251f3c21ca704afae88e42c \ + --hash=sha256:07b6bceea232559d24358832f1cd2ed344bbf05ca83855a5b9698b5f23c5ed60 \ + --hash=sha256:1ef452cc02e0e2f8e3c917b1a5b936ef3280f2c2ca854ee70ac2164d1655f7e6 \ + --hash=sha256:22bf61857c5977f34d4e391476d40f9a3b8c6ab24fb0cac448d42d8f8b9bf7b2 \ + --hash=sha256:299870e3428cbff1cd9f9b34144e76ecdc1d9e3192a8cf5f1b0258f47a239f58 \ + --hash=sha256:2bfc36bfccbe047671170ea5677efd3d5ab730a55d7e45611d76d495e5b96766 \ + --hash=sha256:32e82d5a640febc688c0789e15ea875bf696a10cf358f049e1ed841f01710a9b \ + --hash=sha256:3b2051bdc4bc3f02fa52483f6381cf40d4d48167645241993f9d7ebbd142ed9b \ + --hash=sha256:3f734bd8a08f5185a64fb6abb8f14dc97ec27a689ca808fb7a83cdd38d745e4f \ + --hash=sha256:3f78dd8de3112df8bbd970f0916ac876dc3fbe63810bd1cf7cc5eec4cbac4f04 \ + --hash=sha256:4eabeb48508953ba1f3590ad0773b8daea9e104eec66d661917e9bbcd7125a67 \ + --hash=sha256:4f05ecc33808187f430f249cb1ccab35c38f570b181f2d380fbe253da94b18d8 \ + --hash=sha256:4f4f4cbf23d3afc1526294a31e7b3eaa0f682cc28ac5366065dc1d6bb18bd7be \ + --hash=sha256:5483d5e70aacd06f0aa3effec9fed597c0b50f45060956eeeb1203c44d4338c3 \ + --hash=sha256:56a5f9b46892b115a75d0a1f2292431ad5988461175826600acc69a24cb3edee \ + --hash=sha256:64bb63af8a06f736927d260efdd4dfc5253d42244f281a8063e4b9eea2ddcbc5 \ + --hash=sha256:653f8cbefcf7c6ac4cece2cdef367c4faa2b7c19795d52bd7cbec11a8739a7c1 \ + --hash=sha256:664211d63306e4bd4eec35bf2b4bd9db61c394037911cf2d1804c43b511a49f1 \ + --hash=sha256:6651e6caed66a8fff0fef1a3e81c0ed2253bf361c0fdc834500488732c5d16e9 \ + --hash=sha256:6c1fba6cdfdf105739d3069cf7b07664f2944d82a8098218ab2300a82d8f40fc \ + --hash=sha256:6e64246e6e9044a4534a69dca1283c6ddab6e757be5e6874f69024329b3aa61f \ + --hash=sha256:838390245c7ec137af4993c0c8052f49d5ec79e422b4451bfa37fee9b9ccaa01 \ + --hash=sha256:856b410a14793069d8ba35f33fff667213ea66f2df25a0024cc72a7493c56d4c \ + --hash=sha256:8b932c364c1d1605a91907a41128ed0ee8a2d326fc0fafb2c55cd46f545f4599 \ + --hash=sha256:9086cf6d20f08dae7f296a78f6c77d1f8d24079d448f023ee0eb329078dd35e1 \ + --hash=sha256:9698533c14afa0548188de4968a7932d1f3f965f3f5ba1474de673596bb875af \ + --hash=sha256:9b12b05dd7c28f5068387c1afee8cb94f9d02501e7ef495a7c5c7e27139b96ad \ + --hash=sha256:a884c7426a5bc6fb7fc71a55ad14e66818e13f05b78b20a6f37175f324b7acb8 \ + --hash=sha256:abe9e7f1a3e76286c5f5baf2bf5162d41dc0310da493b34a2c36555f38d928f7 \ + --hash=sha256:bd6fde63b015a27262be06bd6bbdd895273cc2bdf2d4c7e1c83711d26a8fbace \ + --hash=sha256:bda7c62c954f47b87ed9a89f525eee1b318ec7c2162dfdba76c2ccfa334e0caa \ + --hash=sha256:be8a4908dd3f6e965993c0068b006bdbd0474fbcbd1da4893b49356e73fc1557 \ + --hash=sha256:ced65fc3c7d7205267506d854bb1815bb445899cca9d21d1d4b949070a635546 \ + --hash=sha256:dac4279aa05055d3897ab5e5ee5a7b39db121f91df65a530f8b1ac7f9bd93119 \ + --hash=sha256:e4f1863056e3e4f399c285b67fa816f411a7bfa1c81ef50e186126164e396e59 \ + --hash=sha256:ecd85f68b8cd9ab78a0141e87ea9a53b2f31fd9b1350a1c44da1f7481b5363ef \ + --hash=sha256:ed269b83750413e8fc5c96276372f49ee3fcb7ed61c49fe8e5a67f54459a5a4a \ + --hash=sha256:f19b0b80cba73b204dee68501870b11067711d21d243fb6774256d3ca2e5391f \ + --hash=sha256:ffdafb98db7574f9da84c489a10a5d582079a888cb43c64e9e6b0e3fe1034685 # Contains the requirements for the letsencrypt package. # @@ -1338,18 +1503,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==0.40.1 \ - --hash=sha256:afe4d7edc61d4cab8b6f7ab7611d66aaba67d9f0404fa2760bd1cc430b2ec9ec \ - --hash=sha256:8dc81b3044cf401c55fa36c30893887fcb92657df1d76a8848059683df3b10d1 -acme==0.40.1 \ - --hash=sha256:a85387c26fb4fc24511b2579b8c61177b3175fd25e130c5be95a840d9f67d54f \ - --hash=sha256:33bf8686408d5b6b79886a9a43aee691ca754408deaec4fb2bb17b9af48a5ffc -certbot-apache==0.40.1 \ - --hash=sha256:6c4a4e21a17bd8120056595e5670c9a0f86756da0ad269196e8d56fc1b9fec82 \ - --hash=sha256:16404e9e404f0b98c18bd752fad812a45ef7f9b0efa9bbc8589f24a94e67de7c -certbot-nginx==0.40.1 \ - --hash=sha256:acdbfc4ab75ebc810264ee1248332f8e857c5e7776717b7cd53c4ceceb2b4d34 \ - --hash=sha256:014fdda80647ad9e67019b16c7cdaee5d21a750b393bcb98e1300615cc930f4f +certbot==1.1.0 \ + --hash=sha256:66a5cab9267349941604c2c98082bfef85877653c023fc324b1c3869fb16add6 \ + --hash=sha256:46e93661a0db53f416c0f5476d8d2e62bc7259b7660dd983453b85df9ef6e8b8 +acme==1.1.0 \ + --hash=sha256:11b9beba706fb8f652c8910d46dd1939d670cac8169f3c66c18c080ed3353e71 \ + --hash=sha256:c305a20eeb9cb02240347703d497891c13d43a47c794fa100d4dbb479a5370d9 +certbot-apache==1.1.0 \ + --hash=sha256:9c847ff223c2e465e241c78d22f97cee77d5e551df608bed06c55f8627f4cbd2 \ + --hash=sha256:05e84dfe96b72582cde97c490977d8e2d33d440c927a320debb4cf287f6fadcc +certbot-nginx==1.1.0 \ + --hash=sha256:bf06fa2f5059f0fdb7d352c8739e1ed0830db4f0d89e812dab4f081bda6ec7d6 \ + --hash=sha256:0a80ecbd2a30f3757c7652cabfff854ca07873b1cf02ebbe1892786c3b3a5874 UNLIKELY_EOF # ------------------------------------------------------------------------- @@ -1583,6 +1748,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 @@ -1794,30 +1962,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 "$@" diff --git a/certbot-ci/certbot_integration_tests/.coveragerc b/certbot-ci/certbot_integration_tests/.coveragerc index c83880b64..72f7c6adf 100644 --- a/certbot-ci/certbot_integration_tests/.coveragerc +++ b/certbot-ci/certbot_integration_tests/.coveragerc @@ -2,8 +2,8 @@ # Avoid false warnings because certbot packages are not installed in the thread that executes # the coverage: indeed, certbot is launched as a CLI from a subprocess. disable_warnings = module-not-imported,no-data-collected -omit = **/*_test.py,**/tests/*,**/dns_common*,**/certbot_nginx/parser_obj.py +omit = **/*_test.py,**/tests/*,**/dns_common*,**/certbot_nginx/_internal/parser_obj.py [report] # Exclude unit tests in coverage during integration tests. -omit = **/*_test.py,**/tests/*,**/dns_common*,**/certbot_nginx/parser_obj.py +omit = **/*_test.py,**/tests/*,**/dns_common*,**/certbot_nginx/_internal/parser_obj.py diff --git a/certbot-ci/certbot_integration_tests/assets/hook.py b/certbot-ci/certbot_integration_tests/assets/hook.py index ff735a216..39aa72ac5 100755 --- a/certbot-ci/certbot_integration_tests/assets/hook.py +++ b/certbot-ci/certbot_integration_tests/assets/hook.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import sys import os +import sys hook_script_type = os.path.basename(os.path.dirname(sys.argv[1])) if hook_script_type == 'deploy' and ('RENEWED_DOMAINS' not in os.environ or 'RENEWED_LINEAGE' not in os.environ): diff --git a/certbot-ci/certbot_integration_tests/certbot_tests/assertions.py b/certbot-ci/certbot_integration_tests/certbot_tests/assertions.py index 5177ffbd2..1b5914d1a 100644 --- a/certbot-ci/certbot_integration_tests/certbot_tests/assertions.py +++ b/certbot-ci/certbot_integration_tests/certbot_tests/assertions.py @@ -1,5 +1,6 @@ """This module contains advanced assertions for the certbot integration tests.""" import os + try: import grp POSIX_MODE = True diff --git a/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py b/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py index 50c685a57..94e76cf79 100644 --- a/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py +++ b/certbot-ci/certbot_integration_tests/certbot_tests/test_main.py @@ -2,21 +2,25 @@ from __future__ import print_function import os +from os.path import exists +from os.path import join import re import shutil import subprocess import time -from os.path import join, exists import pytest + from certbot_integration_tests.certbot_tests import context as certbot_context -from certbot_integration_tests.certbot_tests.assertions import ( - assert_hook_execution, assert_saved_renew_hook, - assert_cert_count_for_lineage, - assert_world_no_permissions, assert_world_read_permissions, - assert_equals_group_owner, assert_equals_group_permissions, assert_equals_world_read_permissions, - EVERYBODY_SID -) +from certbot_integration_tests.certbot_tests.assertions import assert_cert_count_for_lineage +from certbot_integration_tests.certbot_tests.assertions import assert_equals_group_owner +from certbot_integration_tests.certbot_tests.assertions import assert_equals_group_permissions +from certbot_integration_tests.certbot_tests.assertions import assert_equals_world_read_permissions +from certbot_integration_tests.certbot_tests.assertions import assert_hook_execution +from certbot_integration_tests.certbot_tests.assertions import assert_saved_renew_hook +from certbot_integration_tests.certbot_tests.assertions import assert_world_no_permissions +from certbot_integration_tests.certbot_tests.assertions import assert_world_read_permissions +from certbot_integration_tests.certbot_tests.assertions import EVERYBODY_SID from certbot_integration_tests.utils import misc @@ -62,11 +66,6 @@ def test_registration_override(context): context.certbot(['unregister']) context.certbot(['register', '--email', 'ex1@domain.org,ex2@domain.org']) - # TODO: When `certbot register --update-registration` is fully deprecated, - # delete the two following deprecated uses - context.certbot(['register', '--update-registration', '--email', 'ex1@domain.org']) - context.certbot(['register', '--update-registration', '--email', 'ex1@domain.org,ex2@domain.org']) - context.certbot(['update_account', '--email', 'example@domain.org']) context.certbot(['update_account', '--email', 'ex1@domain.org,ex2@domain.org']) diff --git a/certbot-ci/certbot_integration_tests/conftest.py b/certbot-ci/certbot_integration_tests/conftest.py index d52e4fb58..6eb9ee865 100644 --- a/certbot-ci/certbot_integration_tests/conftest.py +++ b/certbot-ci/certbot_integration_tests/conftest.py @@ -6,9 +6,10 @@ 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 contextlib -import sys import subprocess +import sys from certbot_integration_tests.utils import acme_server as acme_lib diff --git a/certbot-ci/certbot_integration_tests/nginx_tests/context.py b/certbot-ci/certbot_integration_tests/nginx_tests/context.py index 61facc6af..3a769840c 100644 --- a/certbot-ci/certbot_integration_tests/nginx_tests/context.py +++ b/certbot-ci/certbot_integration_tests/nginx_tests/context.py @@ -2,8 +2,9 @@ import os import subprocess from certbot_integration_tests.certbot_tests import context as certbot_context -from certbot_integration_tests.utils import misc, certbot_call from certbot_integration_tests.nginx_tests import nginx_config as config +from certbot_integration_tests.utils import certbot_call +from certbot_integration_tests.utils import misc class IntegrationTestsContext(certbot_context.IntegrationTestsContext): diff --git a/certbot-ci/certbot_integration_tests/utils/acme_server.py b/certbot-ci/certbot_integration_tests/utils/acme_server.py index 9e7ead916..fbf97fef1 100755 --- a/certbot-ci/certbot_integration_tests/utils/acme_server.py +++ b/certbot-ci/certbot_integration_tests/utils/acme_server.py @@ -1,19 +1,22 @@ #!/usr/bin/env python """Module to setup an ACME CA server environment able to run multiple tests in parallel""" from __future__ import print_function + import errno import json +import os +from os.path import join +import shutil +import subprocess +import sys import tempfile import time -import os -import subprocess -import shutil -import sys -from os.path import join import requests -from certbot_integration_tests.utils import misc, proxy, pebble_artifacts +from certbot_integration_tests.utils import misc +from certbot_integration_tests.utils import pebble_artifacts +from certbot_integration_tests.utils import proxy from certbot_integration_tests.utils.constants import * diff --git a/certbot-ci/certbot_integration_tests/utils/certbot_call.py b/certbot-ci/certbot_integration_tests/utils/certbot_call.py index 949852c0a..2ddaa41c8 100755 --- a/certbot-ci/certbot_integration_tests/utils/certbot_call.py +++ b/certbot-ci/certbot_integration_tests/utils/certbot_call.py @@ -1,10 +1,11 @@ #!/usr/bin/env python """Module to call certbot in test mode""" from __future__ import absolute_import + from distutils.version import LooseVersion +import os import subprocess import sys -import os import certbot_integration_tests from certbot_integration_tests.utils.constants import * diff --git a/certbot-ci/certbot_integration_tests/utils/misc.py b/certbot-ci/certbot_integration_tests/utils/misc.py index db910b9ec..b08f11e89 100644 --- a/certbot-ci/certbot_integration_tests/utils/misc.py +++ b/certbot-ci/certbot_integration_tests/utils/misc.py @@ -3,27 +3,27 @@ Misc module contains stateless functions that could be used during pytest execut or outside during setup/teardown of the integration tests environment. """ import contextlib -import logging import errno import multiprocessing import os import re import shutil import stat -import subprocess import sys import tempfile import time import warnings -from distutils.version import LooseVersion -import pkg_resources -import requests -from OpenSSL import crypto from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import ec -from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption -from six.moves import socketserver, SimpleHTTPServer +from cryptography.hazmat.primitives.serialization import Encoding +from cryptography.hazmat.primitives.serialization import NoEncryption +from cryptography.hazmat.primitives.serialization import PrivateFormat +from OpenSSL import crypto +import pkg_resources +import requests +from six.moves import SimpleHTTPServer +from six.moves import socketserver RSA_KEY_TYPE = 'rsa' ECDSA_KEY_TYPE = 'ecdsa' diff --git a/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py b/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py index 2c5dea4a2..9458560e8 100755 --- a/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py +++ b/certbot-ci/certbot_integration_tests/utils/pebble_ocsp_server.py @@ -6,17 +6,18 @@ to serve a mock OCSP responder during integration tests against Pebble. import datetime import re -import requests -from dateutil import parser - -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import serialization, hashes from cryptography import x509 +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives import serialization from cryptography.x509 import ocsp +from dateutil import parser +import requests from six.moves import BaseHTTPServer +from certbot_integration_tests.utils.constants import MOCK_OCSP_SERVER_PORT +from certbot_integration_tests.utils.constants import PEBBLE_MANAGEMENT_URL from certbot_integration_tests.utils.misc import GracefulTCPServer -from certbot_integration_tests.utils.constants import MOCK_OCSP_SERVER_PORT, PEBBLE_MANAGEMENT_URL class _ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler): diff --git a/certbot-ci/certbot_integration_tests/utils/proxy.py b/certbot-ci/certbot_integration_tests/utils/proxy.py index 69248c771..3a16adebf 100644 --- a/certbot-ci/certbot_integration_tests/utils/proxy.py +++ b/certbot-ci/certbot_integration_tests/utils/proxy.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import json -import sys import re +import sys import requests from six.moves import BaseHTTPServer diff --git a/certbot-ci/setup.py b/certbot-ci/setup.py index 025bb3c81..fb82b6ca5 100644 --- a/certbot-ci/setup.py +++ b/certbot-ci/setup.py @@ -1,14 +1,16 @@ +from distutils.version import StrictVersion import sys -from distutils.version import StrictVersion -from setuptools import setup, find_packages, __version__ as setuptools_version - +from setuptools import __version__ as setuptools_version +from setuptools import find_packages +from setuptools import setup version = '0.32.0.dev0' install_requires = [ 'coverage', 'cryptography', + 'docker-compose', 'pyopenssl', 'pytest', 'pytest-cov', diff --git a/certbot-compatibility-test/Dockerfile b/certbot-compatibility-test/Dockerfile index 2716d6fcb..a9996f779 100644 --- a/certbot-compatibility-test/Dockerfile +++ b/certbot-compatibility-test/Dockerfile @@ -14,7 +14,7 @@ RUN /opt/certbot/src/letsencrypt-auto-source/letsencrypt-auto --os-packages-only # the above is not likely to change, so by putting it further up the # Dockerfile we make sure we cache as much as possible -COPY setup.py README.rst CHANGELOG.md MANIFEST.in linter_plugin.py tox.cover.py tox.ini .pylintrc /opt/certbot/src/ +COPY certbot/setup.py certbot/README.rst certbot/CHANGELOG.md certbot/MANIFEST.in linter_plugin.py tox.cover.py tox.ini .pylintrc /opt/certbot/src/ # all above files are necessary for setup.py, however, package source # code directory has to be copied separately to a subdirectory... @@ -38,7 +38,7 @@ ENV PATH /opt/certbot/venv/bin:$PATH RUN /opt/certbot/venv/bin/python \ /opt/certbot/src/tools/pip_install_editable.py \ /opt/certbot/src/acme \ - /opt/certbot/src \ + /opt/certbot/src/certbot \ /opt/certbot/src/certbot-apache \ /opt/certbot/src/certbot-nginx \ /opt/certbot/src/certbot-compatibility-test diff --git a/certbot-compatibility-test/MANIFEST.in b/certbot-compatibility-test/MANIFEST.in index 11762538a..a9d4f5ce7 100644 --- a/certbot-compatibility-test/MANIFEST.in +++ b/certbot-compatibility-test/MANIFEST.in @@ -1,6 +1,5 @@ include LICENSE.txt include README.rst -recursive-include docs * include certbot_compatibility_test/configurators/apache/a2enmod.sh include certbot_compatibility_test/configurators/apache/a2dismod.sh include certbot_compatibility_test/configurators/apache/Dockerfile diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py index 82195264b..a9b1ce87e 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py @@ -6,10 +6,10 @@ import subprocess import mock import zope.interface -from certbot import configuration from certbot import errors as le_errors from certbot import util as certbot_util -from certbot_apache import entrypoint +from certbot._internal import configuration +from certbot_apache._internal import entrypoint from certbot_compatibility_test import errors from certbot_compatibility_test import interfaces from certbot_compatibility_test import util @@ -18,7 +18,6 @@ from certbot_compatibility_test.configurators import common as configurators_com @zope.interface.implementer(interfaces.IConfiguratorProxy) class Proxy(configurators_common.Proxy): - # pylint: disable=too-many-instance-attributes """A common base for Apache test configurators""" def __init__(self, args): @@ -28,7 +27,7 @@ class Proxy(configurators_common.Proxy): self.modules = self.server_root = self.test_conf = self.version = None patch = mock.patch( - "certbot_apache.configurator.display_ops.select_vhost") + "certbot_apache._internal.configurator.display_ops.select_vhost") mock_display = patch.start() mock_display.side_effect = le_errors.PluginError( "Unable to determine vhost") diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/common.py index f8d106f21..b592d6288 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/common.py @@ -8,12 +8,10 @@ from certbot._internal import constants from certbot_compatibility_test import errors from certbot_compatibility_test import util - logger = logging.getLogger(__name__) class Proxy(object): - # pylint: disable=too-many-instance-attributes """A common base for compatibility test configurators""" @classmethod @@ -45,8 +43,7 @@ class Proxy(object): method = getattr(self._configurator, name, None) if callable(method): return method - else: - raise AttributeError() + raise AttributeError() def has_more_configs(self): """Returns true if there are more configs to test""" @@ -84,8 +81,7 @@ class Proxy(object): """Returns the set of domain names that the plugin should find""" if self._all_names: return self._all_names - else: - raise errors.Error("No configuration file loaded") + raise errors.Error("No configuration file loaded") def get_testable_domain_names(self): """Returns the set of domain names that can be tested against""" diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py index 3207cf88a..3011b9823 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -6,19 +6,17 @@ import subprocess import zope.interface from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module - -from certbot import configuration -from certbot_nginx import configurator -from certbot_nginx import constants +from certbot._internal import configuration from certbot_compatibility_test import errors from certbot_compatibility_test import interfaces from certbot_compatibility_test import util from certbot_compatibility_test.configurators import common as configurators_common +from certbot_nginx._internal import configurator +from certbot_nginx._internal import constants @zope.interface.implementer(interfaces.IConfiguratorProxy) class Proxy(configurators_common.Proxy): - # pylint: disable=too-many-instance-attributes """A common base for Nginx test configurators""" def load_config(self): diff --git a/certbot-compatibility-test/certbot_compatibility_test/test_driver.py b/certbot-compatibility-test/certbot_compatibility_test/test_driver.py index 72204367e..2c3f880e0 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/test_driver.py +++ b/certbot-compatibility-test/certbot_compatibility_test/test_driver.py @@ -5,31 +5,27 @@ import filecmp import logging import os import shutil +import sys import tempfile import time -import sys -from urllib3.util import connection import OpenSSL - -from six.moves import xrange # pylint: disable=import-error,redefined-builtin +from urllib3.util import connection from acme import challenges from acme import crypto_util from acme import messages -from acme.magic_typing import List, Tuple # 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 Tuple # pylint: disable=unused-import, no-name-in-module from certbot import achallenges from certbot import errors as le_errors from certbot.tests import acme_util - from certbot_compatibility_test import errors from certbot_compatibility_test import util from certbot_compatibility_test import validator - from certbot_compatibility_test.configurators.apache import common as a_common from certbot_compatibility_test.configurators.nginx import common as n_common - DESCRIPTION = """ Tests Certbot plugins against different server configurations. It is assumed that Docker is already installed. If no test type is specified, all @@ -60,26 +56,27 @@ def test_authenticator(plugin, config, temp_dir): return False success = True - for i in xrange(len(responses)): - if not responses[i]: + for i, response in enumerate(responses): + achall = achalls[i] + if not response: logger.error( "Plugin failed to complete %s for %s in %s", - type(achalls[i]), achalls[i].domain, config) + type(achall), achall.domain, config) success = False - elif isinstance(responses[i], challenges.HTTP01Response): + elif isinstance(response, challenges.HTTP01Response): # We fake the DNS resolution to ensure that any domain is resolved # to the local HTTP server setup for the compatibility tests with _fake_dns_resolution("127.0.0.1"): - verified = responses[i].simple_verify( - achalls[i].chall, achalls[i].domain, + verified = response.simple_verify( + achall.chall, achall.domain, util.JWK.public_key(), port=plugin.http_port) if verified: logger.info( - "http-01 verification for %s succeeded", achalls[i].domain) + "http-01 verification for %s succeeded", achall.domain) else: logger.error( "**** http-01 verification for %s in %s failed", - achalls[i].domain, config) + achall.domain, config) success = False if success: @@ -92,8 +89,7 @@ def test_authenticator(plugin, config, temp_dir): if _dirs_are_unequal(config, backup): logger.error("Challenge cleanup failed for %s", config) return False - else: - logger.info("Challenge cleanup succeeded") + logger.info("Challenge cleanup succeeded") return success @@ -308,7 +304,7 @@ def get_args(): "-e", "--enhance", action="store_true", help="tests the enhancements " "the plugin supports (implicitly includes installer tests)") - for plugin in PLUGINS.itervalues(): + for plugin in PLUGINS.values(): plugin.add_parser_arguments(parser) args = parser.parse_args() diff --git a/certbot-compatibility-test/certbot_compatibility_test/util.py b/certbot-compatibility-test/certbot_compatibility_test/util.py index 4f93e5561..3465b7143 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/util.py +++ b/certbot-compatibility-test/certbot_compatibility_test/util.py @@ -8,12 +8,10 @@ import tarfile import josepy as jose -from certbot.tests import util as test_util from certbot._internal import constants - +from certbot.tests import util as test_util from certbot_compatibility_test import errors - _KEY_BASE = "rsa2048_key.pem" KEY_PATH = test_util.vector_path(_KEY_BASE) KEY = test_util.load_pyopenssl_private_key(_KEY_BASE) diff --git a/certbot-compatibility-test/certbot_compatibility_test/validator.py b/certbot-compatibility-test/certbot_compatibility_test/validator.py index 3455ce82d..796ebbe9d 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/validator.py +++ b/certbot-compatibility-test/certbot_compatibility_test/validator.py @@ -1,15 +1,14 @@ """Validators to determine the current webserver configuration""" import logging import socket -import requests +import requests import six -from six.moves import xrange # pylint: disable=import-error,redefined-builtin +from six.moves import xrange # pylint: disable=import-error, redefined-builtin from acme import crypto_util from acme import errors as acme_errors - logger = logging.getLogger(__name__) diff --git a/certbot-compatibility-test/certbot_compatibility_test/validator_test.py b/certbot-compatibility-test/certbot_compatibility_test/validator_test.py index c4a668c5e..86edbdb55 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/validator_test.py +++ b/certbot-compatibility-test/certbot_compatibility_test/validator_test.py @@ -1,9 +1,9 @@ """Tests for certbot_compatibility_test.validator.""" import unittest -import requests import mock import OpenSSL +import requests from acme import errors as acme_errors from certbot_compatibility_test import validator diff --git a/certbot-compatibility-test/docs/.gitignore b/certbot-compatibility-test/docs/.gitignore deleted file mode 100644 index ba65b13af..000000000 --- a/certbot-compatibility-test/docs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/_build/ diff --git a/certbot-compatibility-test/docs/Makefile b/certbot-compatibility-test/docs/Makefile deleted file mode 100644 index 0c9cf40aa..000000000 --- a/certbot-compatibility-test/docs/Makefile +++ /dev/null @@ -1,192 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/certbot-compatibility-test.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/certbot-compatibility-test.qhc" - -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/certbot-compatibility-test" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/certbot-compatibility-test" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/certbot-compatibility-test/docs/_static/.gitignore b/certbot-compatibility-test/docs/_static/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/certbot-compatibility-test/docs/_templates/.gitignore b/certbot-compatibility-test/docs/_templates/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/certbot-compatibility-test/docs/api.rst b/certbot-compatibility-test/docs/api.rst deleted file mode 100644 index 8668ec5d8..000000000 --- a/certbot-compatibility-test/docs/api.rst +++ /dev/null @@ -1,8 +0,0 @@ -================= -API Documentation -================= - -.. toctree:: - :glob: - - api/** diff --git a/certbot-compatibility-test/docs/api/index.rst b/certbot-compatibility-test/docs/api/index.rst deleted file mode 100644 index fea92d2e5..000000000 --- a/certbot-compatibility-test/docs/api/index.rst +++ /dev/null @@ -1,53 +0,0 @@ -:mod:`certbot_compatibility_test` -------------------------------------- - -.. automodule:: certbot_compatibility_test - :members: - -:mod:`certbot_compatibility_test.errors` -============================================ - -.. automodule:: certbot_compatibility_test.errors - :members: - -:mod:`certbot_compatibility_test.interfaces` -================================================ - -.. automodule:: certbot_compatibility_test.interfaces - :members: - -:mod:`certbot_compatibility_test.test_driver` -================================================= - -.. automodule:: certbot_compatibility_test.test_driver - :members: - -:mod:`certbot_compatibility_test.util` -========================================== - -.. automodule:: certbot_compatibility_test.util - :members: - -:mod:`certbot_compatibility_test.configurators` -=================================================== - -.. automodule:: certbot_compatibility_test.configurators - :members: - -:mod:`certbot_compatibility_test.configurators.apache` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: certbot_compatibility_test.configurators.apache - :members: - -:mod:`certbot_compatibility_test.configurators.apache.apache24` -------------------------------------------------------------------- - -.. automodule:: certbot_compatibility_test.configurators.apache.apache24 - :members: - -:mod:`certbot_compatibility_test.configurators.apache.common` -------------------------------------------------------------------- - -.. automodule:: certbot_compatibility_test.configurators.apache.common - :members: diff --git a/certbot-compatibility-test/docs/conf.py b/certbot-compatibility-test/docs/conf.py deleted file mode 100644 index f89f4b368..000000000 --- a/certbot-compatibility-test/docs/conf.py +++ /dev/null @@ -1,319 +0,0 @@ -# -*- coding: utf-8 -*- -# -# certbot-compatibility-test documentation build configuration file, created by -# sphinx-quickstart on Sun Oct 18 13:40:53 2015. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os -import shlex - - -here = os.path.abspath(os.path.dirname(__file__)) - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath(os.path.join(here, '..'))) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.viewcode', - 'repoze.sphinx.autointerface', -] - -autodoc_member_order = 'bysource' -autodoc_default_flags = ['show-inheritance', 'private-members'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'certbot-compatibility-test' -copyright = u'2014-2015, Let\'s Encrypt Project' -author = u'Certbot Project' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0' -# The full version, including alpha/beta/rc tags. -release = '0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = 'en' - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -default_role = 'py:obj' - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. - -# http://docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs -# on_rtd is whether we are on readthedocs.org -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' -if not on_rtd: # only import and set the theme if we're building docs locally - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -# otherwise, readthedocs.org uses their theme by default, so no need to specify it - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'certbot-compatibility-testdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - #'preamble': '', - - # Latex figure (float) alignment - #'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'certbot-compatibility-test.tex', - u'certbot-compatibility-test Documentation', - u'Certbot Project', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'certbot-compatibility-test', - u'certbot-compatibility-test Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'certbot-compatibility-test', - u'certbot-compatibility-test Documentation', - author, 'certbot-compatibility-test', - 'One line description of project.', 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - - -intersphinx_mapping = { - 'python': ('https://docs.python.org/', None), - 'acme': ('https://acme-python.readthedocs.org/en/latest/', None), - 'certbot': ('https://certbot.eff.org/docs/', None), - 'certbot-apache': ( - 'https://letsencrypt-apache.readthedocs.org/en/latest/', None), - 'certbot-nginx': ( - 'https://letsencrypt-nginx.readthedocs.org/en/latest/', None), -} diff --git a/certbot-compatibility-test/docs/index.rst b/certbot-compatibility-test/docs/index.rst deleted file mode 100644 index a5e71e844..000000000 --- a/certbot-compatibility-test/docs/index.rst +++ /dev/null @@ -1,27 +0,0 @@ -.. certbot-compatibility-test documentation master file, created by - sphinx-quickstart on Sun Oct 18 13:40:53 2015. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to certbot-compatibility-test's documentation! -========================================================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - -.. toctree:: - :maxdepth: 1 - - api - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/certbot-compatibility-test/docs/make.bat b/certbot-compatibility-test/docs/make.bat deleted file mode 100644 index b6c0360f4..000000000 --- a/certbot-compatibility-test/docs/make.bat +++ /dev/null @@ -1,263 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - echo. coverage to run coverage check of the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -REM Check if sphinx-build is available and fallback to Python version if any -%SPHINXBUILD% 2> nul -if errorlevel 9009 goto sphinx_python -goto sphinx_ok - -:sphinx_python - -set SPHINXBUILD=python -m sphinx.__init__ -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -:sphinx_ok - - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\certbot-compatibility-test.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\certbot-compatibility-test.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "coverage" ( - %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage - if errorlevel 1 exit /b 1 - echo. - echo.Testing of coverage in the sources finished, look at the ^ -results in %BUILDDIR%/coverage/python.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/certbot-compatibility-test/nginx/roundtrip.py b/certbot-compatibility-test/nginx/roundtrip.py index 85d283c78..afc68647d 100644 --- a/certbot-compatibility-test/nginx/roundtrip.py +++ b/certbot-compatibility-test/nginx/roundtrip.py @@ -3,7 +3,8 @@ import os import sys -from certbot_nginx import nginxparser +from certbot_nginx._internal import nginxparser + def roundtrip(stuff): success = True diff --git a/certbot-compatibility-test/readthedocs.org.requirements.txt b/certbot-compatibility-test/readthedocs.org.requirements.txt deleted file mode 100644 index c2a0c1110..000000000 --- a/certbot-compatibility-test/readthedocs.org.requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -# readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation -# dependencies), but it allows to specify a requirements.txt file at -# https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) - -# Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead - --e acme --e . --e certbot-apache --e certbot-compatibility-test[docs] diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index 40cde4352..177fd9d31 100644 --- a/certbot-compatibility-test/setup.py +++ b/certbot-compatibility-test/setup.py @@ -1,10 +1,9 @@ import sys -from setuptools import setup from setuptools import find_packages +from setuptools import setup - -version = '1.0.0.dev0' +version = '1.2.0.dev0' install_requires = [ 'certbot', @@ -20,11 +19,6 @@ if sys.version_info < (2, 7, 9): install_requires.append('ndg-httpsclient') install_requires.append('pyasn1') -docs_extras = [ - 'repoze.sphinx.autointerface', - 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags - 'sphinx_rtd_theme', -] setup( name='certbot-compatibility-test', @@ -55,9 +49,6 @@ setup( packages=find_packages(), include_package_data=True, install_requires=install_requires, - extras_require={ - 'docs': docs_extras, - }, entry_points={ 'console_scripts': [ 'certbot-compatibility-test = certbot_compatibility_test.test_driver:main', diff --git a/certbot-dns-cloudflare/MANIFEST.in b/certbot-dns-cloudflare/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-cloudflare/MANIFEST.in +++ b/certbot-dns-cloudflare/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-cloudflare/certbot_dns_cloudflare/_internal/__init__.py b/certbot-dns-cloudflare/certbot_dns_cloudflare/_internal/__init__.py new file mode 100644 index 000000000..93b0672b5 --- /dev/null +++ b/certbot-dns-cloudflare/certbot_dns_cloudflare/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_cloudflare.dns_cloudflare` plugin.""" diff --git a/certbot-dns-cloudflare/certbot_dns_cloudflare/dns_cloudflare.py b/certbot-dns-cloudflare/certbot_dns_cloudflare/_internal/dns_cloudflare.py similarity index 100% rename from certbot-dns-cloudflare/certbot_dns_cloudflare/dns_cloudflare.py rename to certbot-dns-cloudflare/certbot_dns_cloudflare/_internal/dns_cloudflare.py diff --git a/certbot-dns-cloudflare/docs/api.rst b/certbot-dns-cloudflare/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-cloudflare/docs/api.rst +++ b/certbot-dns-cloudflare/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-cloudflare/docs/api/dns_cloudflare.rst b/certbot-dns-cloudflare/docs/api/dns_cloudflare.rst deleted file mode 100644 index 35f525201..000000000 --- a/certbot-dns-cloudflare/docs/api/dns_cloudflare.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_cloudflare.dns_cloudflare` --------------------------------------------- - -.. automodule:: certbot_dns_cloudflare.dns_cloudflare - :members: diff --git a/certbot-dns-cloudflare/docs/conf.py b/certbot-dns-cloudflare/docs/conf.py index aa7809246..97e54421e 100644 --- a/certbot-dns-cloudflare/docs/conf.py +++ b/certbot-dns-cloudflare/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-cloudflare/local-oldest-requirements.txt b/certbot-dns-cloudflare/local-oldest-requirements.txt index 1ee716cd6..cf61c15a5 100644 --- a/certbot-dns-cloudflare/local-oldest-requirements.txt +++ b/certbot-dns-cloudflare/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.29.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-cloudflare/readthedocs.org.requirements.txt b/certbot-dns-cloudflare/readthedocs.org.requirements.txt index b18901111..f1df15227 100644 --- a/certbot-dns-cloudflare/readthedocs.org.requirements.txt +++ b/certbot-dns-cloudflare/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-cloudflare[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-cloudflare[docs]" does not work as +# expected and "pip install -e certbot-dns-cloudflare[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-cloudflare[docs] diff --git a/certbot-dns-cloudflare/setup.py b/certbot-dns-cloudflare/setup.py index 6b72d0a76..0f9dd70dd 100644 --- a/certbot-dns-cloudflare/setup.py +++ b/certbot-dns-cloudflare/setup.py @@ -1,14 +1,16 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.29.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'cloudflare>=1.5.1', 'mock', 'setuptools', @@ -20,6 +22,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-cloudflare', version=version, @@ -30,7 +46,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -60,8 +76,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-cloudflare = certbot_dns_cloudflare.dns_cloudflare:Authenticator', + 'dns-cloudflare = certbot_dns_cloudflare._internal.dns_cloudflare:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_cloudflare', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-cloudflare/certbot_dns_cloudflare/dns_cloudflare_test.py b/certbot-dns-cloudflare/tests/dns_cloudflare_test.py similarity index 96% rename from certbot-dns-cloudflare/certbot_dns_cloudflare/dns_cloudflare_test.py rename to certbot-dns-cloudflare/tests/dns_cloudflare_test.py index 4b9419ca8..b24628b0d 100644 --- a/certbot-dns-cloudflare/certbot_dns_cloudflare/dns_cloudflare_test.py +++ b/certbot-dns-cloudflare/tests/dns_cloudflare_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_cloudflare.dns_cloudflare.""" +"""Tests for certbot_dns_cloudflare._internal.dns_cloudflare.""" import unittest @@ -19,7 +19,7 @@ EMAIL = 'example@example.com' class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthenticatorTest): def setUp(self): - from certbot_dns_cloudflare.dns_cloudflare import Authenticator + from certbot_dns_cloudflare._internal.dns_cloudflare import Authenticator super(AuthenticatorTest, self).setUp() @@ -58,7 +58,7 @@ class CloudflareClientTest(unittest.TestCase): record_id = 2 def setUp(self): - from certbot_dns_cloudflare.dns_cloudflare import _CloudflareClient + from certbot_dns_cloudflare._internal.dns_cloudflare import _CloudflareClient self.cloudflare_client = _CloudflareClient(EMAIL, API_KEY) diff --git a/certbot-dns-cloudxns/MANIFEST.in b/certbot-dns-cloudxns/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-cloudxns/MANIFEST.in +++ b/certbot-dns-cloudxns/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-cloudxns/certbot_dns_cloudxns/_internal/__init__.py b/certbot-dns-cloudxns/certbot_dns_cloudxns/_internal/__init__.py new file mode 100644 index 000000000..e2177417d --- /dev/null +++ b/certbot-dns-cloudxns/certbot_dns_cloudxns/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_cloudxns.dns_cloudxns` plugin.""" diff --git a/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns.py b/certbot-dns-cloudxns/certbot_dns_cloudxns/_internal/dns_cloudxns.py similarity index 100% rename from certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns.py rename to certbot-dns-cloudxns/certbot_dns_cloudxns/_internal/dns_cloudxns.py index 5132137f8..2a0f12ea7 100644 --- a/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns.py +++ b/certbot-dns-cloudxns/certbot_dns_cloudxns/_internal/dns_cloudxns.py @@ -1,8 +1,8 @@ """DNS Authenticator for CloudXNS DNS.""" import logging -import zope.interface from lexicon.providers import cloudxns +import zope.interface from certbot import errors from certbot import interfaces diff --git a/certbot-dns-cloudxns/docs/api.rst b/certbot-dns-cloudxns/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-cloudxns/docs/api.rst +++ b/certbot-dns-cloudxns/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-cloudxns/docs/api/dns_cloudxns.rst b/certbot-dns-cloudxns/docs/api/dns_cloudxns.rst deleted file mode 100644 index be794d1a0..000000000 --- a/certbot-dns-cloudxns/docs/api/dns_cloudxns.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_cloudxns.dns_cloudxns` ----------------------------------------- - -.. automodule:: certbot_dns_cloudxns.dns_cloudxns - :members: diff --git a/certbot-dns-cloudxns/docs/conf.py b/certbot-dns-cloudxns/docs/conf.py index 9e2f4c0e6..1fc05c94c 100644 --- a/certbot-dns-cloudxns/docs/conf.py +++ b/certbot-dns-cloudxns/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-cloudxns/local-oldest-requirements.txt b/certbot-dns-cloudxns/local-oldest-requirements.txt index aefe03f90..1307698d4 100644 --- a/certbot-dns-cloudxns/local-oldest-requirements.txt +++ b/certbot-dns-cloudxns/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-cloudxns/readthedocs.org.requirements.txt b/certbot-dns-cloudxns/readthedocs.org.requirements.txt index ae2ff8165..a9a4d068b 100644 --- a/certbot-dns-cloudxns/readthedocs.org.requirements.txt +++ b/certbot-dns-cloudxns/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-cloudxns[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-cloudxns[docs]" does not work as +# expected and "pip install -e certbot-dns-cloudxns[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-cloudxns[docs] diff --git a/certbot-dns-cloudxns/setup.py b/certbot-dns-cloudxns/setup.py index 4c58d56d0..d4d40e8b3 100644 --- a/certbot-dns-cloudxns/setup.py +++ b/certbot-dns-cloudxns/setup.py @@ -1,14 +1,16 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', @@ -20,6 +22,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-cloudxns', version=version, @@ -30,7 +46,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -60,8 +76,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-cloudxns = certbot_dns_cloudxns.dns_cloudxns:Authenticator', + 'dns-cloudxns = certbot_dns_cloudxns._internal.dns_cloudxns:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_cloudxns', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns_test.py b/certbot-dns-cloudxns/tests/dns_cloudxns_test.py similarity index 82% rename from certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns_test.py rename to certbot-dns-cloudxns/tests/dns_cloudxns_test.py index 6bc1e1f79..a1e3cde89 100644 --- a/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns_test.py +++ b/certbot-dns-cloudxns/tests/dns_cloudxns_test.py @@ -1,9 +1,10 @@ -"""Tests for certbot_dns_cloudxns.dns_cloudxns.""" +"""Tests for certbot_dns_cloudxns._internal.dns_cloudxns.""" import unittest import mock -from requests.exceptions import HTTPError, RequestException +from requests.exceptions import HTTPError +from requests.exceptions import RequestException from certbot.compat import os from certbot.plugins import dns_test_common @@ -24,7 +25,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, def setUp(self): super(AuthenticatorTest, self).setUp() - from certbot_dns_cloudxns.dns_cloudxns import Authenticator + from certbot_dns_cloudxns._internal.dns_cloudxns import Authenticator path = os.path.join(self.tempdir, 'file.ini') dns_test_common.write({"cloudxns_api_key": API_KEY, "cloudxns_secret_key": SECRET}, path) @@ -42,7 +43,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, class CloudXNSLexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLexiconClientTest): def setUp(self): - from certbot_dns_cloudxns.dns_cloudxns import _CloudXNSLexiconClient + from certbot_dns_cloudxns._internal.dns_cloudxns import _CloudXNSLexiconClient self.client = _CloudXNSLexiconClient(API_KEY, SECRET, 0) diff --git a/certbot-dns-digitalocean/MANIFEST.in b/certbot-dns-digitalocean/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-digitalocean/MANIFEST.in +++ b/certbot-dns-digitalocean/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-digitalocean/certbot_dns_digitalocean/_internal/__init__.py b/certbot-dns-digitalocean/certbot_dns_digitalocean/_internal/__init__.py new file mode 100644 index 000000000..0291a9341 --- /dev/null +++ b/certbot-dns-digitalocean/certbot_dns_digitalocean/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_digitalocean.dns_digitalocean` plugin.""" diff --git a/certbot-dns-digitalocean/certbot_dns_digitalocean/dns_digitalocean.py b/certbot-dns-digitalocean/certbot_dns_digitalocean/_internal/dns_digitalocean.py similarity index 100% rename from certbot-dns-digitalocean/certbot_dns_digitalocean/dns_digitalocean.py rename to certbot-dns-digitalocean/certbot_dns_digitalocean/_internal/dns_digitalocean.py diff --git a/certbot-dns-digitalocean/docs/api.rst b/certbot-dns-digitalocean/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-digitalocean/docs/api.rst +++ b/certbot-dns-digitalocean/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-digitalocean/docs/api/dns_digitalocean.rst b/certbot-dns-digitalocean/docs/api/dns_digitalocean.rst deleted file mode 100644 index 8a787987e..000000000 --- a/certbot-dns-digitalocean/docs/api/dns_digitalocean.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_digitalocean.dns_digitalocean` ------------------------------------------------- - -.. automodule:: certbot_dns_digitalocean.dns_digitalocean - :members: diff --git a/certbot-dns-digitalocean/docs/conf.py b/certbot-dns-digitalocean/docs/conf.py index e223b1535..0741e4cea 100644 --- a/certbot-dns-digitalocean/docs/conf.py +++ b/certbot-dns-digitalocean/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-digitalocean/local-oldest-requirements.txt b/certbot-dns-digitalocean/local-oldest-requirements.txt index 1ee716cd6..cf61c15a5 100644 --- a/certbot-dns-digitalocean/local-oldest-requirements.txt +++ b/certbot-dns-digitalocean/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.29.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-digitalocean/readthedocs.org.requirements.txt b/certbot-dns-digitalocean/readthedocs.org.requirements.txt index 08d973ab3..d0cc2f74a 100644 --- a/certbot-dns-digitalocean/readthedocs.org.requirements.txt +++ b/certbot-dns-digitalocean/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-digitalocean[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-digitalocean[docs]" does not work as +# expected and "pip install -e certbot-dns-digitalocean[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-digitalocean[docs] diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index 4dabc207f..62fc85603 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -1,14 +1,16 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.29.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'mock', 'python-digitalocean>=1.11', 'setuptools', @@ -21,6 +23,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-digitalocean', version=version, @@ -31,7 +47,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -61,8 +77,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-digitalocean = certbot_dns_digitalocean.dns_digitalocean:Authenticator', + 'dns-digitalocean = certbot_dns_digitalocean._internal.dns_digitalocean:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_digitalocean', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-digitalocean/certbot_dns_digitalocean/dns_digitalocean_test.py b/certbot-dns-digitalocean/tests/dns_digitalocean_test.py similarity index 96% rename from certbot-dns-digitalocean/certbot_dns_digitalocean/dns_digitalocean_test.py rename to certbot-dns-digitalocean/tests/dns_digitalocean_test.py index 3cb49e9fb..71301a47c 100644 --- a/certbot-dns-digitalocean/certbot_dns_digitalocean/dns_digitalocean_test.py +++ b/certbot-dns-digitalocean/tests/dns_digitalocean_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_digitalocean.dns_digitalocean.""" +"""Tests for certbot_dns_digitalocean._internal.dns_digitalocean.""" import unittest @@ -18,7 +18,7 @@ TOKEN = 'a-token' class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthenticatorTest): def setUp(self): - from certbot_dns_digitalocean.dns_digitalocean import Authenticator + from certbot_dns_digitalocean._internal.dns_digitalocean import Authenticator super(AuthenticatorTest, self).setUp() @@ -57,7 +57,7 @@ class DigitalOceanClientTest(unittest.TestCase): record_content = "bar" def setUp(self): - from certbot_dns_digitalocean.dns_digitalocean import _DigitalOceanClient + from certbot_dns_digitalocean._internal.dns_digitalocean import _DigitalOceanClient self.digitalocean_client = _DigitalOceanClient(TOKEN) diff --git a/certbot-dns-dnsimple/MANIFEST.in b/certbot-dns-dnsimple/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-dnsimple/MANIFEST.in +++ b/certbot-dns-dnsimple/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/__init__.py b/certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/__init__.py new file mode 100644 index 000000000..070927555 --- /dev/null +++ b/certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_dnsimple.dns_dnsimple` plugin.""" diff --git a/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple.py b/certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/dns_dnsimple.py similarity index 100% rename from certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple.py rename to certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/dns_dnsimple.py index ad2a3fa30..8c48d31e7 100644 --- a/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple.py +++ b/certbot-dns-dnsimple/certbot_dns_dnsimple/_internal/dns_dnsimple.py @@ -1,8 +1,8 @@ """DNS Authenticator for DNSimple DNS.""" import logging -import zope.interface from lexicon.providers import dnsimple +import zope.interface from certbot import errors from certbot import interfaces diff --git a/certbot-dns-dnsimple/docs/api.rst b/certbot-dns-dnsimple/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-dnsimple/docs/api.rst +++ b/certbot-dns-dnsimple/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-dnsimple/docs/api/dns_dnsimple.rst b/certbot-dns-dnsimple/docs/api/dns_dnsimple.rst deleted file mode 100644 index b0544107b..000000000 --- a/certbot-dns-dnsimple/docs/api/dns_dnsimple.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_dnsimple.dns_dnsimple` ----------------------------------------- - -.. automodule:: certbot_dns_dnsimple.dns_dnsimple - :members: diff --git a/certbot-dns-dnsimple/docs/conf.py b/certbot-dns-dnsimple/docs/conf.py index da692fb9e..99cc93135 100644 --- a/certbot-dns-dnsimple/docs/conf.py +++ b/certbot-dns-dnsimple/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-dnsimple/local-oldest-requirements.txt b/certbot-dns-dnsimple/local-oldest-requirements.txt index aefe03f90..1307698d4 100644 --- a/certbot-dns-dnsimple/local-oldest-requirements.txt +++ b/certbot-dns-dnsimple/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-dnsimple/readthedocs.org.requirements.txt b/certbot-dns-dnsimple/readthedocs.org.requirements.txt index fef73916c..04163ff34 100644 --- a/certbot-dns-dnsimple/readthedocs.org.requirements.txt +++ b/certbot-dns-dnsimple/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-dnsimple[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-dnsimple[docs]" does not work as +# expected and "pip install -e certbot-dns-dnsimple[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-dnsimple[docs] diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index 20ed5457d..69e20c06b 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -1,15 +1,17 @@ import os -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'mock', 'setuptools', 'zope.interface', @@ -32,6 +34,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-dnsimple', version=version, @@ -42,7 +58,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -72,8 +88,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-dnsimple = certbot_dns_dnsimple.dns_dnsimple:Authenticator', + 'dns-dnsimple = certbot_dns_dnsimple._internal.dns_dnsimple:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_dnsimple', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple_test.py b/certbot-dns-dnsimple/tests/dns_dnsimple_test.py similarity index 86% rename from certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple_test.py rename to certbot-dns-dnsimple/tests/dns_dnsimple_test.py index d84bf71ed..ca5eb4f36 100644 --- a/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple_test.py +++ b/certbot-dns-dnsimple/tests/dns_dnsimple_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_dnsimple.dns_dnsimple.""" +"""Tests for certbot_dns_dnsimple._internal.dns_dnsimple.""" import unittest @@ -19,7 +19,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, def setUp(self): super(AuthenticatorTest, self).setUp() - from certbot_dns_dnsimple.dns_dnsimple import Authenticator + from certbot_dns_dnsimple._internal.dns_dnsimple import Authenticator path = os.path.join(self.tempdir, 'file.ini') dns_test_common.write({"dnsimple_token": TOKEN}, path) @@ -39,7 +39,7 @@ class DNSimpleLexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseL LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized for url: ...') def setUp(self): - from certbot_dns_dnsimple.dns_dnsimple import _DNSimpleLexiconClient + from certbot_dns_dnsimple._internal.dns_dnsimple import _DNSimpleLexiconClient self.client = _DNSimpleLexiconClient(TOKEN, 0) diff --git a/certbot-dns-dnsmadeeasy/MANIFEST.in b/certbot-dns-dnsmadeeasy/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-dnsmadeeasy/MANIFEST.in +++ b/certbot-dns-dnsmadeeasy/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/__init__.py b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/__init__.py new file mode 100644 index 000000000..37350ce0b --- /dev/null +++ b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_dnsmadeeasy.dns_dnsmadeeasy` plugin.""" diff --git a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy.py b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/dns_dnsmadeeasy.py similarity index 100% rename from certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy.py rename to certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/dns_dnsmadeeasy.py index 4cd8721ce..ed3146dce 100644 --- a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy.py +++ b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/_internal/dns_dnsmadeeasy.py @@ -1,8 +1,8 @@ """DNS Authenticator for DNS Made Easy DNS.""" import logging -import zope.interface from lexicon.providers import dnsmadeeasy +import zope.interface from certbot import errors from certbot import interfaces diff --git a/certbot-dns-dnsmadeeasy/docs/api.rst b/certbot-dns-dnsmadeeasy/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-dnsmadeeasy/docs/api.rst +++ b/certbot-dns-dnsmadeeasy/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-dnsmadeeasy/docs/api/dns_dnsmadeeasy.rst b/certbot-dns-dnsmadeeasy/docs/api/dns_dnsmadeeasy.rst deleted file mode 100644 index 81948a77f..000000000 --- a/certbot-dns-dnsmadeeasy/docs/api/dns_dnsmadeeasy.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_dnsmadeeasy.dns_dnsmadeeasy` ------------------------------------- - -.. automodule:: certbot_dns_dnsmadeeasy.dns_dnsmadeeasy - :members: diff --git a/certbot-dns-dnsmadeeasy/docs/conf.py b/certbot-dns-dnsmadeeasy/docs/conf.py index 7d26f9742..1f0c57812 100644 --- a/certbot-dns-dnsmadeeasy/docs/conf.py +++ b/certbot-dns-dnsmadeeasy/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt b/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt index aefe03f90..1307698d4 100644 --- a/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt +++ b/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-dnsmadeeasy/readthedocs.org.requirements.txt b/certbot-dns-dnsmadeeasy/readthedocs.org.requirements.txt index 8f8c6c731..eb205d8f2 100644 --- a/certbot-dns-dnsmadeeasy/readthedocs.org.requirements.txt +++ b/certbot-dns-dnsmadeeasy/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-dnsmadeeasy[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-dnsmadeeasy[docs]" does not work as +# expected and "pip install -e certbot-dns-dnsmadeeasy[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-dnsmadeeasy[docs] diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index 85dcaafa3..c42573554 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -1,14 +1,16 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', @@ -20,6 +22,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-dnsmadeeasy', version=version, @@ -30,7 +46,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -60,8 +76,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-dnsmadeeasy = certbot_dns_dnsmadeeasy.dns_dnsmadeeasy:Authenticator', + 'dns-dnsmadeeasy = certbot_dns_dnsmadeeasy._internal.dns_dnsmadeeasy:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_dnsmadeeasy', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy_test.py b/certbot-dns-dnsmadeeasy/tests/dns_dnsmadeeasy_test.py similarity index 87% rename from certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy_test.py rename to certbot-dns-dnsmadeeasy/tests/dns_dnsmadeeasy_test.py index f0901664c..b94cc7d05 100644 --- a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy_test.py +++ b/certbot-dns-dnsmadeeasy/tests/dns_dnsmadeeasy_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_dnsmadeeasy.dns_dnsmadeeasy.""" +"""Tests for certbot_dns_dnsmadeeasy._internal.dns_dnsmadeeasy.""" import unittest @@ -21,7 +21,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, def setUp(self): super(AuthenticatorTest, self).setUp() - from certbot_dns_dnsmadeeasy.dns_dnsmadeeasy import Authenticator + from certbot_dns_dnsmadeeasy._internal.dns_dnsmadeeasy import Authenticator path = os.path.join(self.tempdir, 'file.ini') dns_test_common.write({"dnsmadeeasy_api_key": API_KEY, @@ -44,7 +44,7 @@ class DNSMadeEasyLexiconClientTest(unittest.TestCase, LOGIN_ERROR = HTTPError('403 Client Error: Forbidden for url: {0}.'.format(DOMAIN)) def setUp(self): - from certbot_dns_dnsmadeeasy.dns_dnsmadeeasy import _DNSMadeEasyLexiconClient + from certbot_dns_dnsmadeeasy._internal.dns_dnsmadeeasy import _DNSMadeEasyLexiconClient self.client = _DNSMadeEasyLexiconClient(API_KEY, SECRET_KEY, 0) diff --git a/certbot-dns-gehirn/MANIFEST.in b/certbot-dns-gehirn/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-gehirn/MANIFEST.in +++ b/certbot-dns-gehirn/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-gehirn/certbot_dns_gehirn/_internal/__init__.py b/certbot-dns-gehirn/certbot_dns_gehirn/_internal/__init__.py new file mode 100644 index 000000000..f8d6485dc --- /dev/null +++ b/certbot-dns-gehirn/certbot_dns_gehirn/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_gehirn.dns_gehirn` plugin.""" diff --git a/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn.py b/certbot-dns-gehirn/certbot_dns_gehirn/_internal/dns_gehirn.py similarity index 100% rename from certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn.py rename to certbot-dns-gehirn/certbot_dns_gehirn/_internal/dns_gehirn.py index e64e62da9..18090c95a 100644 --- a/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn.py +++ b/certbot-dns-gehirn/certbot_dns_gehirn/_internal/dns_gehirn.py @@ -1,8 +1,8 @@ """DNS Authenticator for Gehirn Infrastracture Service DNS.""" import logging -import zope.interface from lexicon.providers import gehirn +import zope.interface from certbot import interfaces from certbot.plugins import dns_common diff --git a/certbot-dns-gehirn/docs/api.rst b/certbot-dns-gehirn/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-gehirn/docs/api.rst +++ b/certbot-dns-gehirn/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-gehirn/docs/api/dns_gehirn.rst b/certbot-dns-gehirn/docs/api/dns_gehirn.rst deleted file mode 100644 index 35a13e9c1..000000000 --- a/certbot-dns-gehirn/docs/api/dns_gehirn.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_gehirn.dns_gehirn` ------------------------------------- - -.. automodule:: certbot_dns_gehirn.dns_gehirn - :members: diff --git a/certbot-dns-gehirn/docs/conf.py b/certbot-dns-gehirn/docs/conf.py index a1b2799fb..527bc3d55 100644 --- a/certbot-dns-gehirn/docs/conf.py +++ b/certbot-dns-gehirn/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-gehirn/local-oldest-requirements.txt b/certbot-dns-gehirn/local-oldest-requirements.txt index aefe03f90..1307698d4 100644 --- a/certbot-dns-gehirn/local-oldest-requirements.txt +++ b/certbot-dns-gehirn/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-gehirn/readthedocs.org.requirements.txt b/certbot-dns-gehirn/readthedocs.org.requirements.txt index d9f4f9823..97af343d9 100644 --- a/certbot-dns-gehirn/readthedocs.org.requirements.txt +++ b/certbot-dns-gehirn/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-gehirn[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-gehirn[docs]" does not work as +# expected and "pip install -e certbot-dns-gehirn[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-gehirn[docs] diff --git a/certbot-dns-gehirn/setup.py b/certbot-dns-gehirn/setup.py index f020354dc..61ba30c0e 100644 --- a/certbot-dns-gehirn/setup.py +++ b/certbot-dns-gehirn/setup.py @@ -1,13 +1,15 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ 'acme>=0.31.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'dns-lexicon>=2.1.22', 'mock', 'setuptools', @@ -19,6 +21,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-gehirn', version=version, @@ -29,7 +45,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -59,8 +75,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-gehirn = certbot_dns_gehirn.dns_gehirn:Authenticator', + 'dns-gehirn = certbot_dns_gehirn._internal.dns_gehirn:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_gehirn', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn_test.py b/certbot-dns-gehirn/tests/dns_gehirn_test.py similarity index 89% rename from certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn_test.py rename to certbot-dns-gehirn/tests/dns_gehirn_test.py index 5a591392b..f5b95b6c3 100644 --- a/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn_test.py +++ b/certbot-dns-gehirn/tests/dns_gehirn_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_gehirn.dns_gehirn.""" +"""Tests for certbot_dns_gehirn._internal.dns_gehirn.""" import unittest @@ -20,7 +20,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, def setUp(self): super(AuthenticatorTest, self).setUp() - from certbot_dns_gehirn.dns_gehirn import Authenticator + from certbot_dns_gehirn._internal.dns_gehirn import Authenticator path = os.path.join(self.tempdir, 'file.ini') dns_test_common.write( @@ -43,7 +43,7 @@ class GehirnLexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLex LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized for url: {0}.'.format(DOMAIN)) def setUp(self): - from certbot_dns_gehirn.dns_gehirn import _GehirnLexiconClient + from certbot_dns_gehirn._internal.dns_gehirn import _GehirnLexiconClient self.client = _GehirnLexiconClient(API_TOKEN, API_SECRET, 0) diff --git a/certbot-dns-google/MANIFEST.in b/certbot-dns-google/MANIFEST.in index c91330e38..a7301ee7f 100644 --- a/certbot-dns-google/MANIFEST.in +++ b/certbot-dns-google/MANIFEST.in @@ -2,3 +2,6 @@ include LICENSE.txt include README.rst recursive-include docs * recursive-include certbot_dns_google/testdata * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-google/certbot_dns_google/_internal/__init__.py b/certbot-dns-google/certbot_dns_google/_internal/__init__.py new file mode 100644 index 000000000..f433213ff --- /dev/null +++ b/certbot-dns-google/certbot_dns_google/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_google.dns_google` plugin.""" diff --git a/certbot-dns-google/certbot_dns_google/dns_google.py b/certbot-dns-google/certbot_dns_google/_internal/dns_google.py similarity index 99% rename from certbot-dns-google/certbot_dns_google/dns_google.py rename to certbot-dns-google/certbot_dns_google/_internal/dns_google.py index b722a38cf..3aa910b52 100644 --- a/certbot-dns-google/certbot_dns_google/dns_google.py +++ b/certbot-dns-google/certbot_dns_google/_internal/dns_google.py @@ -2,11 +2,11 @@ import json import logging -import httplib2 -import zope.interface from googleapiclient import discovery from googleapiclient import errors as googleapiclient_errors +import httplib2 from oauth2client.service_account import ServiceAccountCredentials +import zope.interface from certbot import errors from certbot import interfaces @@ -235,7 +235,7 @@ class _GoogleClient(object): :rtype: `list` of `string` or `None` """ - rrs_request = self.dns.resourceRecordSets() # pylint: disable=no-member + rrs_request = self.dns.resourceRecordSets() request = rrs_request.list(managedZone=zone_id, project=self.project_id) # Add dot as the API returns absolute domains record_name += "." diff --git a/certbot-dns-google/docs/api.rst b/certbot-dns-google/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-google/docs/api.rst +++ b/certbot-dns-google/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-google/docs/api/dns_google.rst b/certbot-dns-google/docs/api/dns_google.rst deleted file mode 100644 index 6f5459934..000000000 --- a/certbot-dns-google/docs/api/dns_google.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_google.dns_google` ------------------------------------- - -.. automodule:: certbot_dns_google.dns_google - :members: diff --git a/certbot-dns-google/docs/conf.py b/certbot-dns-google/docs/conf.py index bbb343ee8..b2ddcfb34 100644 --- a/certbot-dns-google/docs/conf.py +++ b/certbot-dns-google/docs/conf.py @@ -18,6 +18,7 @@ # import os import sys + sys.path.insert(0, os.path.abspath('_ext')) @@ -38,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'] diff --git a/certbot-dns-google/local-oldest-requirements.txt b/certbot-dns-google/local-oldest-requirements.txt index 1ee716cd6..cf61c15a5 100644 --- a/certbot-dns-google/local-oldest-requirements.txt +++ b/certbot-dns-google/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.29.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-google/readthedocs.org.requirements.txt b/certbot-dns-google/readthedocs.org.requirements.txt index 6ea393f86..fe97cee94 100644 --- a/certbot-dns-google/readthedocs.org.requirements.txt +++ b/certbot-dns-google/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-google[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-google[docs]" does not work as +# expected and "pip install -e certbot-dns-google[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-google[docs] diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index 61d365189..d53ed9723 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -1,14 +1,16 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.29.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'google-api-python-client>=1.5.5', 'mock', 'oauth2client>=4.0', @@ -23,6 +25,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-google', version=version, @@ -33,7 +49,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -63,8 +79,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-google = certbot_dns_google.dns_google:Authenticator', + 'dns-google = certbot_dns_google._internal.dns_google:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_google', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-google/certbot_dns_google/dns_google_test.py b/certbot-dns-google/tests/dns_google_test.py similarity index 89% rename from certbot-dns-google/certbot_dns_google/dns_google_test.py rename to certbot-dns-google/tests/dns_google_test.py index 288357bc1..647a75b05 100644 --- a/certbot-dns-google/certbot_dns_google/dns_google_test.py +++ b/certbot-dns-google/tests/dns_google_test.py @@ -1,12 +1,12 @@ -"""Tests for certbot_dns_google.dns_google.""" +"""Tests for certbot_dns_google._internal.dns_google.""" import unittest -import mock from googleapiclient import discovery from googleapiclient.errors import Error from googleapiclient.http import HttpMock from httplib2 import ServerNotFoundError +import mock from certbot import errors from certbot.compat import os @@ -25,7 +25,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthentic def setUp(self): super(AuthenticatorTest, self).setUp() - from certbot_dns_google.dns_google import Authenticator + from certbot_dns_google._internal.dns_google import Authenticator path = os.path.join(self.tempdir, 'file.json') open(path, "wb").close() @@ -68,7 +68,7 @@ class GoogleClientTest(unittest.TestCase): change = "an-id" def _setUp_client_with_mock(self, zone_request_side_effect): - from certbot_dns_google.dns_google import _GoogleClient + from certbot_dns_google._internal.dns_google import _GoogleClient pwd = os.path.dirname(__file__) rel_path = 'testdata/discovery.json' @@ -96,18 +96,18 @@ class GoogleClientTest(unittest.TestCase): @mock.patch('googleapiclient.discovery.build') @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google._GoogleClient.get_project_id') + @mock.patch('certbot_dns_google._internal.dns_google._GoogleClient.get_project_id') def test_client_without_credentials(self, get_project_id_mock, credential_mock, unused_discovery_mock): - from certbot_dns_google.dns_google import _GoogleClient + from certbot_dns_google._internal.dns_google import _GoogleClient _GoogleClient(None) self.assertFalse(credential_mock.called) self.assertTrue(get_project_id_mock.called) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) - @mock.patch('certbot_dns_google.dns_google._GoogleClient.get_project_id') + @mock.patch('certbot_dns_google._internal.dns_google._GoogleClient.get_project_id') def test_add_txt_record(self, get_project_id_mock, credential_mock): client, changes = self._setUp_client_with_mock([{'managedZones': [{'id': self.zone}]}]) credential_mock.assert_called_once_with('/not/a/real/path.json', mock.ANY) @@ -133,7 +133,7 @@ class GoogleClientTest(unittest.TestCase): project=PROJECT_ID) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_add_txt_record_and_poll(self, unused_credential_mock): client, changes = self._setUp_client_with_mock([{'managedZones': [{'id': self.zone}]}]) @@ -151,12 +151,13 @@ class GoogleClientTest(unittest.TestCase): project=PROJECT_ID) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_add_txt_record_delete_old(self, unused_credential_mock): client, changes = self._setUp_client_with_mock( [{'managedZones': [{'id': self.zone}]}]) - mock_get_rrs = "certbot_dns_google.dns_google._GoogleClient.get_existing_txt_rrset" + # pylint: disable=line-too-long + mock_get_rrs = "certbot_dns_google._internal.dns_google._GoogleClient.get_existing_txt_rrset" with mock.patch(mock_get_rrs) as mock_rrs: mock_rrs.return_value = ["sample-txt-contents"] client.add_txt_record(DOMAIN, self.record_name, self.record_content, self.record_ttl) @@ -165,7 +166,7 @@ class GoogleClientTest(unittest.TestCase): changes.create.call_args_list[0][1]["body"]["deletions"][0]["rrdatas"]) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_add_txt_record_noop(self, unused_credential_mock): client, changes = self._setUp_client_with_mock( @@ -175,7 +176,7 @@ class GoogleClientTest(unittest.TestCase): self.assertFalse(changes.create.called) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_add_txt_record_error_during_zone_lookup(self, unused_credential_mock): client, unused_changes = self._setUp_client_with_mock(API_ERROR) @@ -184,7 +185,7 @@ class GoogleClientTest(unittest.TestCase): DOMAIN, self.record_name, self.record_content, self.record_ttl) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_add_txt_record_zone_not_found(self, unused_credential_mock): client, unused_changes = self._setUp_client_with_mock([{'managedZones': []}, @@ -194,7 +195,7 @@ class GoogleClientTest(unittest.TestCase): DOMAIN, self.record_name, self.record_content, self.record_ttl) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_add_txt_record_error_during_add(self, unused_credential_mock): client, changes = self._setUp_client_with_mock([{'managedZones': [{'id': self.zone}]}]) @@ -204,12 +205,13 @@ class GoogleClientTest(unittest.TestCase): DOMAIN, self.record_name, self.record_content, self.record_ttl) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_del_txt_record(self, unused_credential_mock): client, changes = self._setUp_client_with_mock([{'managedZones': [{'id': self.zone}]}]) - mock_get_rrs = "certbot_dns_google.dns_google._GoogleClient.get_existing_txt_rrset" + # pylint: disable=line-too-long + mock_get_rrs = "certbot_dns_google._internal.dns_google._GoogleClient.get_existing_txt_rrset" with mock.patch(mock_get_rrs) as mock_rrs: mock_rrs.return_value = ["\"sample-txt-contents\"", "\"example-txt-contents\""] @@ -243,7 +245,7 @@ class GoogleClientTest(unittest.TestCase): project=PROJECT_ID) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_del_txt_record_error_during_zone_lookup(self, unused_credential_mock): client, unused_changes = self._setUp_client_with_mock(API_ERROR) @@ -251,7 +253,7 @@ class GoogleClientTest(unittest.TestCase): client.del_txt_record(DOMAIN, self.record_name, self.record_content, self.record_ttl) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_del_txt_record_zone_not_found(self, unused_credential_mock): client, unused_changes = self._setUp_client_with_mock([{'managedZones': []}, @@ -260,7 +262,7 @@ class GoogleClientTest(unittest.TestCase): client.del_txt_record(DOMAIN, self.record_name, self.record_content, self.record_ttl) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_del_txt_record_error_during_delete(self, unused_credential_mock): client, changes = self._setUp_client_with_mock([{'managedZones': [{'id': self.zone}]}]) @@ -269,7 +271,7 @@ class GoogleClientTest(unittest.TestCase): client.del_txt_record(DOMAIN, self.record_name, self.record_content, self.record_ttl) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_get_existing(self, unused_credential_mock): client, unused_changes = self._setUp_client_with_mock( @@ -281,12 +283,11 @@ class GoogleClientTest(unittest.TestCase): self.assertEqual(not_found, None) @mock.patch('oauth2client.service_account.ServiceAccountCredentials.from_json_keyfile_name') - @mock.patch('certbot_dns_google.dns_google.open', + @mock.patch('certbot_dns_google._internal.dns_google.open', mock.mock_open(read_data='{"project_id": "' + PROJECT_ID + '"}'), create=True) def test_get_existing_fallback(self, unused_credential_mock): client, unused_changes = self._setUp_client_with_mock( [{'managedZones': [{'id': self.zone}]}]) - # pylint: disable=no-member mock_execute = client.dns.resourceRecordSets.return_value.list.return_value.execute mock_execute.side_effect = API_ERROR @@ -294,7 +295,7 @@ class GoogleClientTest(unittest.TestCase): self.assertFalse(rrset) def test_get_project_id(self): - from certbot_dns_google.dns_google import _GoogleClient + from certbot_dns_google._internal.dns_google import _GoogleClient response = DummyResponse() response.status = 200 diff --git a/certbot-dns-google/certbot_dns_google/testdata/discovery.json b/certbot-dns-google/tests/testdata/discovery.json similarity index 100% rename from certbot-dns-google/certbot_dns_google/testdata/discovery.json rename to certbot-dns-google/tests/testdata/discovery.json diff --git a/certbot-dns-linode/MANIFEST.in b/certbot-dns-linode/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-linode/MANIFEST.in +++ b/certbot-dns-linode/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-linode/certbot_dns_linode/_internal/__init__.py b/certbot-dns-linode/certbot_dns_linode/_internal/__init__.py new file mode 100644 index 000000000..9090d92d3 --- /dev/null +++ b/certbot-dns-linode/certbot_dns_linode/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_linode.dns_linode` plugin.""" diff --git a/certbot-dns-linode/certbot_dns_linode/dns_linode.py b/certbot-dns-linode/certbot_dns_linode/_internal/dns_linode.py similarity index 100% rename from certbot-dns-linode/certbot_dns_linode/dns_linode.py rename to certbot-dns-linode/certbot_dns_linode/_internal/dns_linode.py index 507ad5e53..ea6046849 100644 --- a/certbot-dns-linode/certbot_dns_linode/dns_linode.py +++ b/certbot-dns-linode/certbot_dns_linode/_internal/dns_linode.py @@ -2,9 +2,9 @@ import logging import re -import zope.interface from lexicon.providers import linode from lexicon.providers import linode4 +import zope.interface from certbot import errors from certbot import interfaces diff --git a/certbot-dns-linode/docs/api.rst b/certbot-dns-linode/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-linode/docs/api.rst +++ b/certbot-dns-linode/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-linode/docs/api/dns_linode.rst b/certbot-dns-linode/docs/api/dns_linode.rst deleted file mode 100644 index 6380b3eba..000000000 --- a/certbot-dns-linode/docs/api/dns_linode.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_linode.dns_linode` ------------------------------------------------- - -.. automodule:: certbot_dns_linode.dns_linode - :members: diff --git a/certbot-dns-linode/docs/conf.py b/certbot-dns-linode/docs/conf.py index 1fb721400..c6d564b7a 100644 --- a/certbot-dns-linode/docs/conf.py +++ b/certbot-dns-linode/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-linode/local-oldest-requirements.txt b/certbot-dns-linode/local-oldest-requirements.txt index 838e70c69..a8bd7449a 100644 --- a/certbot-dns-linode/local-oldest-requirements.txt +++ b/certbot-dns-linode/local-oldest-requirements.txt @@ -1,4 +1,4 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 dns-lexicon==2.2.3 diff --git a/certbot-dns-linode/readthedocs.org.requirements.txt b/certbot-dns-linode/readthedocs.org.requirements.txt index 47449454f..3d28f43bf 100644 --- a/certbot-dns-linode/readthedocs.org.requirements.txt +++ b/certbot-dns-linode/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-linode[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-linode[docs]" does not work as +# expected and "pip install -e certbot-dns-linode[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-linode[docs] diff --git a/certbot-dns-linode/setup.py b/certbot-dns-linode/setup.py index 807e9b889..1e698c229 100644 --- a/certbot-dns-linode/setup.py +++ b/certbot-dns-linode/setup.py @@ -1,12 +1,15 @@ -from setuptools import setup -from setuptools import find_packages +import sys -version = '1.0.0.dev0' +from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand + +version = '1.2.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ 'acme>=0.31.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'dns-lexicon>=2.2.3', 'mock', 'setuptools', @@ -18,6 +21,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-linode', version=version, @@ -28,7 +45,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -58,8 +75,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-linode = certbot_dns_linode.dns_linode:Authenticator', + 'dns-linode = certbot_dns_linode._internal.dns_linode:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_linode', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-linode/certbot_dns_linode/dns_linode_test.py b/certbot-dns-linode/tests/dns_linode_test.py similarity index 95% rename from certbot-dns-linode/certbot_dns_linode/dns_linode_test.py rename to certbot-dns-linode/tests/dns_linode_test.py index 153f8b51d..3cf615486 100644 --- a/certbot-dns-linode/certbot_dns_linode/dns_linode_test.py +++ b/certbot-dns-linode/tests/dns_linode_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_linode.dns_linode.""" +"""Tests for certbot_dns_linode._internal.dns_linode.""" import unittest @@ -9,7 +9,7 @@ from certbot.compat import os from certbot.plugins import dns_test_common from certbot.plugins import dns_test_common_lexicon from certbot.tests import util as test_util -from certbot_dns_linode.dns_linode import Authenticator +from certbot_dns_linode._internal.dns_linode import Authenticator TOKEN = 'a-token' TOKEN_V3 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ64' @@ -121,7 +121,7 @@ class LinodeLexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLex DOMAIN_NOT_FOUND = Exception('Domain not found') def setUp(self): - from certbot_dns_linode.dns_linode import _LinodeLexiconClient + from certbot_dns_linode._internal.dns_linode import _LinodeLexiconClient self.client = _LinodeLexiconClient(TOKEN, 3) @@ -133,7 +133,7 @@ class Linode4LexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLe DOMAIN_NOT_FOUND = Exception('Domain not found') def setUp(self): - from certbot_dns_linode.dns_linode import _LinodeLexiconClient + from certbot_dns_linode._internal.dns_linode import _LinodeLexiconClient self.client = _LinodeLexiconClient(TOKEN, 4) diff --git a/certbot-dns-luadns/MANIFEST.in b/certbot-dns-luadns/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-luadns/MANIFEST.in +++ b/certbot-dns-luadns/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-luadns/certbot_dns_luadns/_internal/__init__.py b/certbot-dns-luadns/certbot_dns_luadns/_internal/__init__.py new file mode 100644 index 000000000..8ab0a00e2 --- /dev/null +++ b/certbot-dns-luadns/certbot_dns_luadns/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_luadns.dns_luadns` plugin.""" diff --git a/certbot-dns-luadns/certbot_dns_luadns/dns_luadns.py b/certbot-dns-luadns/certbot_dns_luadns/_internal/dns_luadns.py similarity index 100% rename from certbot-dns-luadns/certbot_dns_luadns/dns_luadns.py rename to certbot-dns-luadns/certbot_dns_luadns/_internal/dns_luadns.py index 7cdd4c8e1..7c18c7131 100644 --- a/certbot-dns-luadns/certbot_dns_luadns/dns_luadns.py +++ b/certbot-dns-luadns/certbot_dns_luadns/_internal/dns_luadns.py @@ -1,8 +1,8 @@ """DNS Authenticator for LuaDNS DNS.""" import logging -import zope.interface from lexicon.providers import luadns +import zope.interface from certbot import errors from certbot import interfaces diff --git a/certbot-dns-luadns/docs/api.rst b/certbot-dns-luadns/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-luadns/docs/api.rst +++ b/certbot-dns-luadns/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-luadns/docs/api/dns_luadns.rst b/certbot-dns-luadns/docs/api/dns_luadns.rst deleted file mode 100644 index 9aecbaf05..000000000 --- a/certbot-dns-luadns/docs/api/dns_luadns.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_luadns.dns_luadns` ----------------------------------- - -.. automodule:: certbot_dns_luadns.dns_luadns - :members: diff --git a/certbot-dns-luadns/docs/conf.py b/certbot-dns-luadns/docs/conf.py index bd81d5a5f..8e9d49988 100644 --- a/certbot-dns-luadns/docs/conf.py +++ b/certbot-dns-luadns/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-luadns/local-oldest-requirements.txt b/certbot-dns-luadns/local-oldest-requirements.txt index aefe03f90..1307698d4 100644 --- a/certbot-dns-luadns/local-oldest-requirements.txt +++ b/certbot-dns-luadns/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-luadns/readthedocs.org.requirements.txt b/certbot-dns-luadns/readthedocs.org.requirements.txt index acb51e4ef..6f467dc7c 100644 --- a/certbot-dns-luadns/readthedocs.org.requirements.txt +++ b/certbot-dns-luadns/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-luadns[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-luadns[docs]" does not work as +# expected and "pip install -e certbot-dns-luadns[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-luadns[docs] diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index 3ee8fb2fe..0df82b08f 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -1,14 +1,16 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', @@ -20,6 +22,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-luadns', version=version, @@ -30,7 +46,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -60,8 +76,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-luadns = certbot_dns_luadns.dns_luadns:Authenticator', + 'dns-luadns = certbot_dns_luadns._internal.dns_luadns:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_luadns', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-luadns/certbot_dns_luadns/dns_luadns_test.py b/certbot-dns-luadns/tests/dns_luadns_test.py similarity index 87% rename from certbot-dns-luadns/certbot_dns_luadns/dns_luadns_test.py rename to certbot-dns-luadns/tests/dns_luadns_test.py index 73cef6521..934d3e103 100644 --- a/certbot-dns-luadns/certbot_dns_luadns/dns_luadns_test.py +++ b/certbot-dns-luadns/tests/dns_luadns_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_luadns.dns_luadns.""" +"""Tests for certbot_dns_luadns._internal.dns_luadns.""" import unittest @@ -20,7 +20,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, def setUp(self): super(AuthenticatorTest, self).setUp() - from certbot_dns_luadns.dns_luadns import Authenticator + from certbot_dns_luadns._internal.dns_luadns import Authenticator path = os.path.join(self.tempdir, 'file.ini') dns_test_common.write({"luadns_email": EMAIL, "luadns_token": TOKEN}, path) @@ -40,7 +40,7 @@ class LuaDNSLexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLex LOGIN_ERROR = HTTPError("401 Client Error: Unauthorized for url: ...") def setUp(self): - from certbot_dns_luadns.dns_luadns import _LuaDNSLexiconClient + from certbot_dns_luadns._internal.dns_luadns import _LuaDNSLexiconClient self.client = _LuaDNSLexiconClient(EMAIL, TOKEN, 0) diff --git a/certbot-dns-nsone/MANIFEST.in b/certbot-dns-nsone/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-nsone/MANIFEST.in +++ b/certbot-dns-nsone/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-nsone/certbot_dns_nsone/_internal/__init__.py b/certbot-dns-nsone/certbot_dns_nsone/_internal/__init__.py new file mode 100644 index 000000000..40a095edf --- /dev/null +++ b/certbot-dns-nsone/certbot_dns_nsone/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_nsone.dns_nsone` plugin.""" diff --git a/certbot-dns-nsone/certbot_dns_nsone/dns_nsone.py b/certbot-dns-nsone/certbot_dns_nsone/_internal/dns_nsone.py similarity index 100% rename from certbot-dns-nsone/certbot_dns_nsone/dns_nsone.py rename to certbot-dns-nsone/certbot_dns_nsone/_internal/dns_nsone.py index b585ddb7a..f5af37389 100644 --- a/certbot-dns-nsone/certbot_dns_nsone/dns_nsone.py +++ b/certbot-dns-nsone/certbot_dns_nsone/_internal/dns_nsone.py @@ -1,8 +1,8 @@ """DNS Authenticator for NS1 DNS.""" import logging -import zope.interface from lexicon.providers import nsone +import zope.interface from certbot import errors from certbot import interfaces diff --git a/certbot-dns-nsone/docs/api.rst b/certbot-dns-nsone/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-nsone/docs/api.rst +++ b/certbot-dns-nsone/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-nsone/docs/api/dns_nsone.rst b/certbot-dns-nsone/docs/api/dns_nsone.rst deleted file mode 100644 index 788ce732a..000000000 --- a/certbot-dns-nsone/docs/api/dns_nsone.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_nsone.dns_nsone` ----------------------------------- - -.. automodule:: certbot_dns_nsone.dns_nsone - :members: diff --git a/certbot-dns-nsone/docs/conf.py b/certbot-dns-nsone/docs/conf.py index cffe2a25c..5531959ed 100644 --- a/certbot-dns-nsone/docs/conf.py +++ b/certbot-dns-nsone/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-nsone/local-oldest-requirements.txt b/certbot-dns-nsone/local-oldest-requirements.txt index aefe03f90..1307698d4 100644 --- a/certbot-dns-nsone/local-oldest-requirements.txt +++ b/certbot-dns-nsone/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-nsone/readthedocs.org.requirements.txt b/certbot-dns-nsone/readthedocs.org.requirements.txt index dbdee4480..bf17eae30 100644 --- a/certbot-dns-nsone/readthedocs.org.requirements.txt +++ b/certbot-dns-nsone/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-nsone[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-nsone[docs]" does not work as +# expected and "pip install -e certbot-dns-nsone[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-nsone[docs] diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index 2cc44406f..b98ec96c5 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -1,14 +1,16 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', @@ -20,6 +22,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-nsone', version=version, @@ -30,7 +46,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -60,8 +76,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-nsone = certbot_dns_nsone.dns_nsone:Authenticator', + 'dns-nsone = certbot_dns_nsone._internal.dns_nsone:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_nsone', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-nsone/certbot_dns_nsone/dns_nsone_test.py b/certbot-dns-nsone/tests/dns_nsone_test.py similarity index 88% rename from certbot-dns-nsone/certbot_dns_nsone/dns_nsone_test.py rename to certbot-dns-nsone/tests/dns_nsone_test.py index b2db2f603..dd6168f08 100644 --- a/certbot-dns-nsone/certbot_dns_nsone/dns_nsone_test.py +++ b/certbot-dns-nsone/tests/dns_nsone_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_nsone.dns_nsone.""" +"""Tests for certbot_dns_nsone._internal.dns_nsone.""" import unittest @@ -20,7 +20,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, def setUp(self): super(AuthenticatorTest, self).setUp() - from certbot_dns_nsone.dns_nsone import Authenticator + from certbot_dns_nsone._internal.dns_nsone import Authenticator path = os.path.join(self.tempdir, 'file.ini') dns_test_common.write({"nsone_api_key": API_KEY}, path) @@ -40,7 +40,7 @@ class NS1LexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLexico LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized for url: {0}.'.format(DOMAIN)) def setUp(self): - from certbot_dns_nsone.dns_nsone import _NS1LexiconClient + from certbot_dns_nsone._internal.dns_nsone import _NS1LexiconClient self.client = _NS1LexiconClient(API_KEY, 0) diff --git a/certbot-dns-ovh/MANIFEST.in b/certbot-dns-ovh/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-ovh/MANIFEST.in +++ b/certbot-dns-ovh/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-ovh/certbot_dns_ovh/_internal/__init__.py b/certbot-dns-ovh/certbot_dns_ovh/_internal/__init__.py new file mode 100644 index 000000000..133694b9e --- /dev/null +++ b/certbot-dns-ovh/certbot_dns_ovh/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_ovh.dns_ovh` plugin.""" diff --git a/certbot-dns-ovh/certbot_dns_ovh/dns_ovh.py b/certbot-dns-ovh/certbot_dns_ovh/_internal/dns_ovh.py similarity index 100% rename from certbot-dns-ovh/certbot_dns_ovh/dns_ovh.py rename to certbot-dns-ovh/certbot_dns_ovh/_internal/dns_ovh.py index 84771b0a8..a495983f2 100644 --- a/certbot-dns-ovh/certbot_dns_ovh/dns_ovh.py +++ b/certbot-dns-ovh/certbot_dns_ovh/_internal/dns_ovh.py @@ -1,8 +1,8 @@ """DNS Authenticator for OVH DNS.""" import logging -import zope.interface from lexicon.providers import ovh +import zope.interface from certbot import errors from certbot import interfaces diff --git a/certbot-dns-ovh/docs/api.rst b/certbot-dns-ovh/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-ovh/docs/api.rst +++ b/certbot-dns-ovh/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-ovh/docs/api/dns_ovh.rst b/certbot-dns-ovh/docs/api/dns_ovh.rst deleted file mode 100644 index 79863d05f..000000000 --- a/certbot-dns-ovh/docs/api/dns_ovh.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_ovh.dns_ovh` ------------------------------- - -.. automodule:: certbot_dns_ovh.dns_ovh - :members: diff --git a/certbot-dns-ovh/docs/conf.py b/certbot-dns-ovh/docs/conf.py index 57194666e..56e24a920 100644 --- a/certbot-dns-ovh/docs/conf.py +++ b/certbot-dns-ovh/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-ovh/local-oldest-requirements.txt b/certbot-dns-ovh/local-oldest-requirements.txt index 1116b6dfc..c55e0d570 100644 --- a/certbot-dns-ovh/local-oldest-requirements.txt +++ b/certbot-dns-ovh/local-oldest-requirements.txt @@ -1,4 +1,4 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 dns-lexicon==2.7.14 diff --git a/certbot-dns-ovh/readthedocs.org.requirements.txt b/certbot-dns-ovh/readthedocs.org.requirements.txt index 0780e12a1..3c21ae0ce 100644 --- a/certbot-dns-ovh/readthedocs.org.requirements.txt +++ b/certbot-dns-ovh/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-ovh[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-ovh[docs]" does not work as +# expected and "pip install -e certbot-dns-ovh[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-ovh[docs] diff --git a/certbot-dns-ovh/setup.py b/certbot-dns-ovh/setup.py index b3abce754..1b2e0cad2 100644 --- a/certbot-dns-ovh/setup.py +++ b/certbot-dns-ovh/setup.py @@ -1,14 +1,16 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.31.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider 'mock', 'setuptools', @@ -20,6 +22,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-ovh', version=version, @@ -30,7 +46,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -60,8 +76,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-ovh = certbot_dns_ovh.dns_ovh:Authenticator', + 'dns-ovh = certbot_dns_ovh._internal.dns_ovh:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_ovh', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-ovh/certbot_dns_ovh/dns_ovh_test.py b/certbot-dns-ovh/tests/dns_ovh_test.py similarity index 90% rename from certbot-dns-ovh/certbot_dns_ovh/dns_ovh_test.py rename to certbot-dns-ovh/tests/dns_ovh_test.py index b48a85055..a420239ab 100644 --- a/certbot-dns-ovh/certbot_dns_ovh/dns_ovh_test.py +++ b/certbot-dns-ovh/tests/dns_ovh_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_ovh.dns_ovh.""" +"""Tests for certbot_dns_ovh._internal.dns_ovh.""" import unittest @@ -22,7 +22,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, def setUp(self): super(AuthenticatorTest, self).setUp() - from certbot_dns_ovh.dns_ovh import Authenticator + from certbot_dns_ovh._internal.dns_ovh import Authenticator path = os.path.join(self.tempdir, 'file.ini') credentials = { @@ -48,7 +48,7 @@ class OVHLexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLexico LOGIN_ERROR = HTTPError('403 Client Error: Forbidden for url: https://eu.api.ovh.com/1.0/...') def setUp(self): - from certbot_dns_ovh.dns_ovh import _OVHLexiconClient + from certbot_dns_ovh._internal.dns_ovh import _OVHLexiconClient self.client = _OVHLexiconClient( ENDPOINT, APPLICATION_KEY, APPLICATION_SECRET, CONSUMER_KEY, 0 diff --git a/certbot-dns-rfc2136/MANIFEST.in b/certbot-dns-rfc2136/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-rfc2136/MANIFEST.in +++ b/certbot-dns-rfc2136/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-rfc2136/certbot_dns_rfc2136/_internal/__init__.py b/certbot-dns-rfc2136/certbot_dns_rfc2136/_internal/__init__.py new file mode 100644 index 000000000..44894bb35 --- /dev/null +++ b/certbot-dns-rfc2136/certbot_dns_rfc2136/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_rfc2136.dns_rfc2136` plugin.""" diff --git a/certbot-dns-rfc2136/certbot_dns_rfc2136/dns_rfc2136.py b/certbot-dns-rfc2136/certbot_dns_rfc2136/_internal/dns_rfc2136.py similarity index 100% rename from certbot-dns-rfc2136/certbot_dns_rfc2136/dns_rfc2136.py rename to certbot-dns-rfc2136/certbot_dns_rfc2136/_internal/dns_rfc2136.py diff --git a/certbot-dns-rfc2136/docs/api.rst b/certbot-dns-rfc2136/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-rfc2136/docs/api.rst +++ b/certbot-dns-rfc2136/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-rfc2136/docs/api/dns_rfc2136.rst b/certbot-dns-rfc2136/docs/api/dns_rfc2136.rst deleted file mode 100644 index f5e98454a..000000000 --- a/certbot-dns-rfc2136/docs/api/dns_rfc2136.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_rfc2136.dns_rfc2136` --------------------------------------- - -.. automodule:: certbot_dns_rfc2136.dns_rfc2136 - :members: diff --git a/certbot-dns-rfc2136/docs/conf.py b/certbot-dns-rfc2136/docs/conf.py index 8cc5d595f..c0d55078e 100644 --- a/certbot-dns-rfc2136/docs/conf.py +++ b/certbot-dns-rfc2136/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-rfc2136/local-oldest-requirements.txt b/certbot-dns-rfc2136/local-oldest-requirements.txt index 1ee716cd6..cf61c15a5 100644 --- a/certbot-dns-rfc2136/local-oldest-requirements.txt +++ b/certbot-dns-rfc2136/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.29.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-rfc2136/readthedocs.org.requirements.txt b/certbot-dns-rfc2136/readthedocs.org.requirements.txt index df89018ce..2cf4f70f8 100644 --- a/certbot-dns-rfc2136/readthedocs.org.requirements.txt +++ b/certbot-dns-rfc2136/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-rfc2136[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-rfc2136[docs]" does not work as +# expected and "pip install -e certbot-dns-rfc2136[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-rfc2136[docs] diff --git a/certbot-dns-rfc2136/setup.py b/certbot-dns-rfc2136/setup.py index 0da7cc98a..1af30681a 100644 --- a/certbot-dns-rfc2136/setup.py +++ b/certbot-dns-rfc2136/setup.py @@ -1,14 +1,16 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.29.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'dnspython', 'mock', 'setuptools', @@ -20,6 +22,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-rfc2136', version=version, @@ -30,7 +46,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -60,8 +76,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-rfc2136 = certbot_dns_rfc2136.dns_rfc2136:Authenticator', + 'dns-rfc2136 = certbot_dns_rfc2136._internal.dns_rfc2136:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_rfc2136', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-rfc2136/certbot_dns_rfc2136/dns_rfc2136_test.py b/certbot-dns-rfc2136/tests/dns_rfc2136_test.py similarity index 97% rename from certbot-dns-rfc2136/certbot_dns_rfc2136/dns_rfc2136_test.py rename to certbot-dns-rfc2136/tests/dns_rfc2136_test.py index 1950ee62e..c767dba23 100644 --- a/certbot-dns-rfc2136/certbot_dns_rfc2136/dns_rfc2136_test.py +++ b/certbot-dns-rfc2136/tests/dns_rfc2136_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_rfc2136.dns_rfc2136.""" +"""Tests for certbot_dns_rfc2136._internal.dns_rfc2136.""" import unittest @@ -23,7 +23,7 @@ VALID_CONFIG = {"rfc2136_server": SERVER, "rfc2136_name": NAME, "rfc2136_secret" class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthenticatorTest): def setUp(self): - from certbot_dns_rfc2136.dns_rfc2136 import Authenticator + from certbot_dns_rfc2136._internal.dns_rfc2136 import Authenticator super(AuthenticatorTest, self).setUp() @@ -73,7 +73,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthentic class RFC2136ClientTest(unittest.TestCase): def setUp(self): - from certbot_dns_rfc2136.dns_rfc2136 import _RFC2136Client + from certbot_dns_rfc2136._internal.dns_rfc2136 import _RFC2136Client self.rfc2136_client = _RFC2136Client(SERVER, PORT, NAME, SECRET, dns.tsig.HMAC_MD5) diff --git a/certbot-dns-route53/MANIFEST.in b/certbot-dns-route53/MANIFEST.in index ca37a7baf..fc62028b0 100644 --- a/certbot-dns-route53/MANIFEST.in +++ b/certbot-dns-route53/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-route53/certbot_dns_route53/_internal/__init__.py b/certbot-dns-route53/certbot_dns_route53/_internal/__init__.py new file mode 100644 index 000000000..ac9ead791 --- /dev/null +++ b/certbot-dns-route53/certbot_dns_route53/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_route53.dns_route53` plugin.""" diff --git a/certbot-dns-route53/certbot_dns_route53/dns_route53.py b/certbot-dns-route53/certbot_dns_route53/_internal/dns_route53.py similarity index 94% rename from certbot-dns-route53/certbot_dns_route53/dns_route53.py rename to certbot-dns-route53/certbot_dns_route53/_internal/dns_route53.py index e32017b34..637558304 100644 --- a/certbot-dns-route53/certbot_dns_route53/dns_route53.py +++ b/certbot-dns-route53/certbot_dns_route53/_internal/dns_route53.py @@ -4,15 +4,17 @@ import logging import time import boto3 +from botocore.exceptions import ClientError +from botocore.exceptions import NoCredentialsError import zope.interface -from botocore.exceptions import NoCredentialsError, ClientError +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 certbot import errors from certbot import interfaces from certbot.plugins import dns_common -from acme.magic_typing import DefaultDict, List, Dict # pylint: disable=unused-import, no-name-in-module - logger = logging.getLogger(__name__) INSTRUCTIONS = ( @@ -20,6 +22,7 @@ INSTRUCTIONS = ( "https://boto3.readthedocs.io/en/latest/guide/configuration.html#best-practices-for-configuring-credentials " # pylint: disable=line-too-long "and add the necessary permissions for Route53 access.") + @zope.interface.implementer(interfaces.IAuthenticator) @zope.interface.provider(interfaces.IPluginFactory) class Authenticator(dns_common.DNSAuthenticator): diff --git a/certbot-dns-route53/certbot_dns_route53/authenticator.py b/certbot-dns-route53/certbot_dns_route53/authenticator.py index 53215ea1d..2987934a1 100644 --- a/certbot-dns-route53/certbot_dns_route53/authenticator.py +++ b/certbot-dns-route53/certbot_dns_route53/authenticator.py @@ -1,16 +1,17 @@ -"""Shim around `~certbot_dns_route53.dns_route53` for backwards compatibility.""" +"""Shim around `~certbot_dns_route53._internal.dns_route53` for backwards compatibility.""" import warnings import zope.interface from certbot import interfaces -from certbot_dns_route53 import dns_route53 +from certbot_dns_route53._internal import dns_route53 @zope.interface.implementer(interfaces.IAuthenticator) @zope.interface.provider(interfaces.IPluginFactory) class Authenticator(dns_route53.Authenticator): - """Shim around `~certbot_dns_route53.dns_route53.Authenticator` for backwards compatibility.""" + """Shim around `~certbot_dns_route53._internal.dns_route53.Authenticator` + for backwards compatibility.""" hidden = True diff --git a/certbot-dns-route53/docs/api.rst b/certbot-dns-route53/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-route53/docs/api.rst +++ b/certbot-dns-route53/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-route53/docs/api/authenticator.rst b/certbot-dns-route53/docs/api/authenticator.rst deleted file mode 100644 index 2d96a419b..000000000 --- a/certbot-dns-route53/docs/api/authenticator.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_route53.authenticator` ----------------------------------------- - -.. automodule:: certbot_dns_route53.authenticator - :members: diff --git a/certbot-dns-route53/docs/api/dns_route53.rst b/certbot-dns-route53/docs/api/dns_route53.rst deleted file mode 100644 index 7573f2e19..000000000 --- a/certbot-dns-route53/docs/api/dns_route53.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_route53.dns_route53` --------------------------------------- - -.. automodule:: certbot_dns_route53.dns_route53 - :members: diff --git a/certbot-dns-route53/docs/conf.py b/certbot-dns-route53/docs/conf.py index 25a7c6e4d..c2eb880ac 100644 --- a/certbot-dns-route53/docs/conf.py +++ b/certbot-dns-route53/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-route53/local-oldest-requirements.txt b/certbot-dns-route53/local-oldest-requirements.txt index 1ee716cd6..cf61c15a5 100644 --- a/certbot-dns-route53/local-oldest-requirements.txt +++ b/certbot-dns-route53/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.29.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-route53/readthedocs.org.requirements.txt b/certbot-dns-route53/readthedocs.org.requirements.txt index 660a90d0e..993225eac 100644 --- a/certbot-dns-route53/readthedocs.org.requirements.txt +++ b/certbot-dns-route53/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-route53[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-route53[docs]" does not work as +# expected and "pip install -e certbot-dns-route53[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-route53[docs] diff --git a/certbot-dns-route53/setup.py b/certbot-dns-route53/setup.py index 548a567b4..70e19048b 100644 --- a/certbot-dns-route53/setup.py +++ b/certbot-dns-route53/setup.py @@ -1,19 +1,36 @@ -from setuptools import setup -from setuptools import find_packages +import sys -version = '1.0.0.dev0' +from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand + +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ 'acme>=0.29.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'boto3', 'mock', 'setuptools', 'zope.interface', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-route53', version=version, @@ -24,7 +41,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -51,9 +68,11 @@ setup( keywords=['certbot', 'route53', 'aws'], entry_points={ 'certbot.plugins': [ - 'dns-route53 = certbot_dns_route53.dns_route53:Authenticator', + 'dns-route53 = certbot_dns_route53._internal.dns_route53:Authenticator', 'certbot-route53:auth = certbot_dns_route53.authenticator:Authenticator' ], }, + tests_require=["pytest"], test_suite='certbot_dns_route53', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-route53/certbot_dns_route53/dns_route53_test.py b/certbot-dns-route53/tests/dns_route53_test.py similarity index 96% rename from certbot-dns-route53/certbot_dns_route53/dns_route53_test.py rename to certbot-dns-route53/tests/dns_route53_test.py index 36c391690..85ec259b1 100644 --- a/certbot-dns-route53/certbot_dns_route53/dns_route53_test.py +++ b/certbot-dns-route53/tests/dns_route53_test.py @@ -1,9 +1,10 @@ -"""Tests for certbot_dns_route53.dns_route53.Authenticator""" +"""Tests for certbot_dns_route53._internal.dns_route53.Authenticator""" import unittest +from botocore.exceptions import ClientError +from botocore.exceptions import NoCredentialsError import mock -from botocore.exceptions import NoCredentialsError, ClientError from certbot import errors from certbot.compat import os @@ -15,7 +16,7 @@ class AuthenticatorTest(unittest.TestCase, dns_test_common.BaseAuthenticatorTest # pylint: disable=protected-access def setUp(self): - from certbot_dns_route53.dns_route53 import Authenticator + from certbot_dns_route53._internal.dns_route53 import Authenticator super(AuthenticatorTest, self).setUp() @@ -122,7 +123,7 @@ class ClientTest(unittest.TestCase): } def setUp(self): - from certbot_dns_route53.dns_route53 import Authenticator + from certbot_dns_route53._internal.dns_route53 import Authenticator super(ClientTest, self).setUp() diff --git a/certbot-dns-route53/tools/tester.pkoch-macos_sierra.sh b/certbot-dns-route53/tools/tester.pkoch-macos_sierra.sh deleted file mode 100755 index dbbaa2251..000000000 --- a/certbot-dns-route53/tools/tester.pkoch-macos_sierra.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# I just wanted a place to dump the incantations I use for testing. -set -e - -brew install openssl libffi - -rm -rf scratch; mkdir scratch - -virtualenv scratch/venv -p /usr/local/bin/python2.7 -scratch/venv/bin/pip install -U pip setuptools - -CPPFLAGS=-I/usr/local/opt/openssl/include LDFLAGS=-L/usr/local/opt/openssl/lib scratch/venv/bin/pip install -e . - -scratch/venv/bin/certbot certonly -n --agree-tos --test-cert --email pkoch@lifeonmars.pt -a certbot-route53:auth -d pkoch.lifeonmars.pt --work-dir scratch --config-dir scratch --logs-dir scratch - -rm -rf scratch diff --git a/certbot-dns-sakuracloud/MANIFEST.in b/certbot-dns-sakuracloud/MANIFEST.in index 18f018c08..5a661cef6 100644 --- a/certbot-dns-sakuracloud/MANIFEST.in +++ b/certbot-dns-sakuracloud/MANIFEST.in @@ -1,3 +1,6 @@ include LICENSE.txt include README.rst recursive-include docs * +recursive-include tests * +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/__init__.py b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/__init__.py new file mode 100644 index 000000000..0c8839024 --- /dev/null +++ b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_sakuracloud.dns_sakuracloud` plugin.""" diff --git a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud.py b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/dns_sakuracloud.py similarity index 100% rename from certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud.py rename to certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/dns_sakuracloud.py index d6e20894d..25042bfc6 100644 --- a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud.py +++ b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/_internal/dns_sakuracloud.py @@ -1,8 +1,8 @@ """DNS Authenticator for Sakura Cloud DNS.""" import logging -import zope.interface from lexicon.providers import sakuracloud +import zope.interface from certbot import interfaces from certbot.plugins import dns_common diff --git a/certbot-dns-sakuracloud/docs/api.rst b/certbot-dns-sakuracloud/docs/api.rst index 8668ec5d8..ac13c3df2 100644 --- a/certbot-dns-sakuracloud/docs/api.rst +++ b/certbot-dns-sakuracloud/docs/api.rst @@ -2,7 +2,4 @@ API Documentation ================= -.. toctree:: - :glob: - - api/** +Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API. diff --git a/certbot-dns-sakuracloud/docs/api/dns_sakuracloud.rst b/certbot-dns-sakuracloud/docs/api/dns_sakuracloud.rst deleted file mode 100644 index 74692e15b..000000000 --- a/certbot-dns-sakuracloud/docs/api/dns_sakuracloud.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_dns_sakuracloud.dns_sakuracloud` ----------------------------------------------- - -.. automodule:: certbot_dns_sakuracloud.dns_sakuracloud - :members: diff --git a/certbot-dns-sakuracloud/docs/conf.py b/certbot-dns-sakuracloud/docs/conf.py index e14fe1d4c..70a4d7434 100644 --- a/certbot-dns-sakuracloud/docs/conf.py +++ b/certbot-dns-sakuracloud/docs/conf.py @@ -17,6 +17,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os + # import sys # sys.path.insert(0, os.path.abspath('.')) @@ -37,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'] diff --git a/certbot-dns-sakuracloud/local-oldest-requirements.txt b/certbot-dns-sakuracloud/local-oldest-requirements.txt index aefe03f90..1307698d4 100644 --- a/certbot-dns-sakuracloud/local-oldest-requirements.txt +++ b/certbot-dns-sakuracloud/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. acme[dev]==0.31.0 -certbot[dev]==0.39.0 +certbot[dev]==1.1.0 diff --git a/certbot-dns-sakuracloud/readthedocs.org.requirements.txt b/certbot-dns-sakuracloud/readthedocs.org.requirements.txt index 3f46d95ef..07bc8a289 100644 --- a/certbot-dns-sakuracloud/readthedocs.org.requirements.txt +++ b/certbot-dns-sakuracloud/readthedocs.org.requirements.txt @@ -1,12 +1,12 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot-dns-sakuracloud[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# in --editable mode (-e), just "pip install certbot-dns-sakuracloud[docs]" does not work as +# expected and "pip install -e certbot-dns-sakuracloud[docs]" must be used instead -e acme --e . +-e certbot -e certbot-dns-sakuracloud[docs] diff --git a/certbot-dns-sakuracloud/setup.py b/certbot-dns-sakuracloud/setup.py index 7c5bfe7f3..2c762bc4a 100644 --- a/certbot-dns-sakuracloud/setup.py +++ b/certbot-dns-sakuracloud/setup.py @@ -1,13 +1,15 @@ -from setuptools import setup +import sys + from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand - -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ 'acme>=0.31.0', - 'certbot>=0.39.0', + 'certbot>=1.0.0', 'dns-lexicon>=2.1.23', 'mock', 'setuptools', @@ -19,6 +21,20 @@ docs_extras = [ 'sphinx_rtd_theme', ] +class PyTest(TestCommand): + user_options = [] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = '' + + def run_tests(self): + import shlex + # import here, cause outside the eggs aren't loaded + import pytest + errno = pytest.main(shlex.split(self.pytest_args)) + sys.exit(errno) + setup( name='certbot-dns-sakuracloud', version=version, @@ -29,7 +45,7 @@ setup( license='Apache License 2.0', python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Apache Software License', @@ -59,8 +75,10 @@ setup( }, entry_points={ 'certbot.plugins': [ - 'dns-sakuracloud = certbot_dns_sakuracloud.dns_sakuracloud:Authenticator', + 'dns-sakuracloud = certbot_dns_sakuracloud._internal.dns_sakuracloud:Authenticator', ], }, + tests_require=["pytest"], test_suite='certbot_dns_sakuracloud', + cmdclass={"test": PyTest}, ) diff --git a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud_test.py b/certbot-dns-sakuracloud/tests/dns_sakuracloud_test.py similarity index 88% rename from certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud_test.py rename to certbot-dns-sakuracloud/tests/dns_sakuracloud_test.py index 10abc29e2..16890b5a9 100644 --- a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud_test.py +++ b/certbot-dns-sakuracloud/tests/dns_sakuracloud_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot_dns_sakuracloud.dns_sakuracloud.""" +"""Tests for certbot_dns_sakuracloud._internal.dns_sakuracloud.""" import unittest @@ -20,7 +20,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, def setUp(self): super(AuthenticatorTest, self).setUp() - from certbot_dns_sakuracloud.dns_sakuracloud import Authenticator + from certbot_dns_sakuracloud._internal.dns_sakuracloud import Authenticator path = os.path.join(self.tempdir, 'file.ini') dns_test_common.write( @@ -44,7 +44,7 @@ class SakuraCloudLexiconClientTest(unittest.TestCase, LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized for url: {0}.'.format(DOMAIN)) def setUp(self): - from certbot_dns_sakuracloud.dns_sakuracloud import _SakuraCloudLexiconClient + from certbot_dns_sakuracloud._internal.dns_sakuracloud import _SakuraCloudLexiconClient self.client = _SakuraCloudLexiconClient(API_TOKEN, API_SECRET, 0) diff --git a/certbot-nginx/MANIFEST.in b/certbot-nginx/MANIFEST.in index 3a22c4873..65b27877e 100644 --- a/certbot-nginx/MANIFEST.in +++ b/certbot-nginx/MANIFEST.in @@ -1,5 +1,6 @@ include LICENSE.txt include README.rst -recursive-include docs * -recursive-include certbot_nginx/tests/testdata * -recursive-include certbot_nginx/tls_configs *.conf +recursive-include tests * +recursive-include certbot_nginx/_internal/tls_configs *.conf +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot-nginx/certbot_nginx/_internal/__init__.py b/certbot-nginx/certbot_nginx/_internal/__init__.py new file mode 100644 index 000000000..71d79b0c2 --- /dev/null +++ b/certbot-nginx/certbot_nginx/_internal/__init__.py @@ -0,0 +1 @@ +"""Certbot nginx plugin internal implementation.""" diff --git a/certbot-nginx/certbot_nginx/configurator.py b/certbot-nginx/certbot_nginx/_internal/configurator.py similarity index 97% rename from certbot-nginx/certbot_nginx/configurator.py rename to certbot-nginx/certbot_nginx/_internal/configurator.py index 177c0ea40..70d9d87f8 100644 --- a/certbot-nginx/certbot_nginx/configurator.py +++ b/certbot-nginx/certbot_nginx/_internal/configurator.py @@ -1,6 +1,6 @@ """Nginx Configuration""" # 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 # pylint: disable=no-name-in-module, import-error import logging import re import socket @@ -8,28 +8,27 @@ import subprocess import tempfile import time -import pkg_resources - import OpenSSL +import pkg_resources import zope.interface from acme import challenges from acme import crypto_util as acme_crypto_util -from acme.magic_typing import List, Dict, Set # pylint: disable=unused-import, no-name-in-module - +from 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 certbot import crypto_util from certbot import errors from certbot import interfaces from certbot import util from certbot.compat import os from certbot.plugins import common - -from certbot_nginx import constants -from certbot_nginx import display_ops -from certbot_nginx import http_01 -from certbot_nginx import nginxparser -from certbot_nginx import obj # pylint: disable=unused-import -from certbot_nginx import parser +from certbot_nginx._internal import constants +from certbot_nginx._internal import display_ops +from certbot_nginx._internal import http_01 +from certbot_nginx._internal import nginxparser +from certbot_nginx._internal import obj # pylint: disable=unused-import +from certbot_nginx._internal import parser NAME_RANK = 0 START_WILDCARD_RANK = 1 @@ -44,7 +43,6 @@ logger = logging.getLogger(__name__) @zope.interface.implementer(interfaces.IAuthenticator, interfaces.IInstaller) @zope.interface.provider(interfaces.IPluginFactory) class NginxConfigurator(common.Installer): - # pylint: disable=too-many-instance-attributes,too-many-public-methods """Nginx configurator. .. todo:: Add proper support for comments in the config. Currently, @@ -54,7 +52,7 @@ class NginxConfigurator(common.Installer): :type config: :class:`~certbot.interfaces.IConfig` :ivar parser: Handles low level parsing - :type parser: :class:`~certbot_nginx.parser` + :type parser: :class:`~certbot_nginx._internal.parser` :ivar str save_notes: Human-readable config change notes @@ -155,7 +153,7 @@ class NginxConfigurator(common.Installer): config_filename = "options-ssl-nginx-old.conf" return pkg_resources.resource_filename( - "certbot_nginx", os.path.join("tls_configs", config_filename)) + "certbot_nginx", os.path.join("_internal", "tls_configs", config_filename)) @property def mod_ssl_conf(self): @@ -285,7 +283,7 @@ class NginxConfigurator(common.Installer): filtered_vhosts[name] = vhost # Only unique VHost objects - dialog_input = set([vhost for vhost in filtered_vhosts.values()]) + dialog_input = set(filtered_vhosts.values()) # Ask the user which of names to enable, expect list of names back return_vhosts = display_ops.select_vhost_multiple(list(dialog_input)) @@ -324,7 +322,7 @@ class NginxConfigurator(common.Installer): MisconfigurationError. :returns: ssl vhosts associated with name - :rtype: list of :class:`~certbot_nginx.obj.VirtualHost` + :rtype: list of :class:`~certbot_nginx._internal.obj.VirtualHost` """ if util.is_wildcard_domain(target_name): @@ -443,7 +441,7 @@ class NginxConfigurator(common.Installer): :param list matches: list of dicts containing the vhost, the matching name, and the numerical rank :returns: the most matching vhost - :rtype: :class:`~certbot_nginx.obj.VirtualHost` + :rtype: :class:`~certbot_nginx._internal.obj.VirtualHost` """ if not matches: @@ -530,7 +528,7 @@ class NginxConfigurator(common.Installer): MisconfigurationError. :returns: vhosts associated with name - :rtype: list of :class:`~certbot_nginx.obj.VirtualHost` + :rtype: list of :class:`~certbot_nginx._internal.obj.VirtualHost` """ if util.is_wildcard_domain(target_name): @@ -644,7 +642,7 @@ class NginxConfigurator(common.Installer): Make a server SSL by adding new listen and SSL directives. :param vhost: The vhost to add SSL to. - :type vhost: :class:`~certbot_nginx.obj.VirtualHost` + :type vhost: :class:`~certbot_nginx._internal.obj.VirtualHost` """ https_port = self.config.https_port @@ -772,9 +770,9 @@ class NginxConfigurator(common.Installer): :param vhost: The server block to break up into two. :param list only_directives: If this exists, only duplicate these directives when splitting the block. - :type vhost: :class:`~certbot_nginx.obj.VirtualHost` + :type vhost: :class:`~certbot_nginx._internal.obj.VirtualHost` :returns: tuple (http_vhost, https_vhost) - :rtype: tuple of type :class:`~certbot_nginx.obj.VirtualHost` + :rtype: tuple of type :class:`~certbot_nginx._internal.obj.VirtualHost` """ http_vhost = self.parser.duplicate_vhost(vhost, only_directives=only_directives) diff --git a/certbot-nginx/certbot_nginx/constants.py b/certbot-nginx/certbot_nginx/_internal/constants.py similarity index 100% rename from certbot-nginx/certbot_nginx/constants.py rename to certbot-nginx/certbot_nginx/_internal/constants.py diff --git a/certbot-nginx/certbot_nginx/display_ops.py b/certbot-nginx/certbot_nginx/_internal/display_ops.py similarity index 99% rename from certbot-nginx/certbot_nginx/display_ops.py rename to certbot-nginx/certbot_nginx/_internal/display_ops.py index 9b973d8d3..bbb47f98a 100644 --- a/certbot-nginx/certbot_nginx/display_ops.py +++ b/certbot-nginx/certbot_nginx/_internal/display_ops.py @@ -4,10 +4,8 @@ import logging import zope.component from certbot import interfaces - import certbot.display.util as display_util - logger = logging.getLogger(__name__) diff --git a/certbot-nginx/certbot_nginx/http_01.py b/certbot-nginx/certbot_nginx/_internal/http_01.py similarity index 96% rename from certbot-nginx/certbot_nginx/http_01.py rename to certbot-nginx/certbot_nginx/_internal/http_01.py index 4dcc5324f..97b111576 100644 --- a/certbot-nginx/certbot_nginx/http_01.py +++ b/certbot-nginx/certbot_nginx/_internal/http_01.py @@ -3,15 +3,12 @@ import logging from acme import challenges -from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - +from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module from certbot import errors from certbot.compat import os from certbot.plugins import common - -from certbot_nginx import obj -from certbot_nginx import nginxparser - +from certbot_nginx._internal import nginxparser +from certbot_nginx._internal import obj logger = logging.getLogger(__name__) @@ -110,7 +107,7 @@ class NginxHttp01(common.ChallengePerformer): def _default_listen_addresses(self): """Finds addresses for a challenge block to listen on. - :returns: list of :class:`certbot_nginx.obj.Addr` to apply + :returns: list of :class:`certbot_nginx._internal.obj.Addr` to apply :rtype: list """ addresses = [] # type: List[obj.Addr] diff --git a/certbot-nginx/certbot_nginx/nginxparser.py b/certbot-nginx/certbot_nginx/_internal/nginxparser.py similarity index 95% rename from certbot-nginx/certbot_nginx/nginxparser.py rename to certbot-nginx/certbot_nginx/_internal/nginxparser.py index bfb75adcc..4fa1362a0 100644 --- a/certbot-nginx/certbot_nginx/nginxparser.py +++ b/certbot-nginx/certbot_nginx/_internal/nginxparser.py @@ -3,10 +3,18 @@ import copy import logging -from pyparsing import ( - Literal, White, Forward, Group, Optional, OneOrMore, QuotedString, Regex, ZeroOrMore, Combine) -from pyparsing import stringEnd +from pyparsing import Combine +from pyparsing import Forward +from pyparsing import Group +from pyparsing import Literal +from pyparsing import OneOrMore +from pyparsing import Optional +from pyparsing import QuotedString +from pyparsing import Regex from pyparsing import restOfLine +from pyparsing import stringEnd +from pyparsing import White +from pyparsing import ZeroOrMore import six logger = logging.getLogger(__name__) @@ -63,7 +71,6 @@ class RawNginxParser(object): return self.parse().asList() class RawNginxDumper(object): - # pylint: disable=too-few-public-methods """A class that dumps nginx configuration from the provided tree.""" def __init__(self, blocks): self.blocks = blocks @@ -179,12 +186,11 @@ class UnspacedList(list): """ if not isinstance(inbound, list): # str or None - return (inbound, inbound) + return inbound, inbound else: if not hasattr(inbound, "spaced"): inbound = UnspacedList(inbound) - return (inbound, inbound.spaced) - + return inbound, inbound.spaced def insert(self, i, x): item, spaced_item = self._coerce(x) diff --git a/certbot-nginx/certbot_nginx/obj.py b/certbot-nginx/certbot_nginx/_internal/obj.py similarity index 97% rename from certbot-nginx/certbot_nginx/obj.py rename to certbot-nginx/certbot_nginx/_internal/obj.py index b14be81ea..1a92c8b37 100644 --- a/certbot-nginx/certbot_nginx/obj.py +++ b/certbot-nginx/certbot_nginx/_internal/obj.py @@ -37,7 +37,6 @@ class Addr(common.Addr): CANONICAL_UNSPECIFIED_ADDRESS = UNSPECIFIED_IPV4_ADDRESSES[0] def __init__(self, host, port, ssl, default, ipv6, ipv6only): - # pylint: disable=too-many-arguments super(Addr, self).__init__((host, port)) self.ssl = ssl self.default = default @@ -122,7 +121,7 @@ class Addr(common.Addr): def __hash__(self): # pylint: disable=useless-super-delegation # Python 3 requires explicit overridden for __hash__ - # See certbot-apache/certbot_apache/obj.py for more information + # See certbot-apache/certbot_apache/_internal/obj.py for more information return super(Addr, self).__hash__() def super_eq(self, other): @@ -145,7 +144,7 @@ class Addr(common.Addr): return False -class VirtualHost(object): # pylint: disable=too-few-public-methods +class VirtualHost(object): """Represents an Nginx Virtualhost. :ivar str filep: file path of VH @@ -162,7 +161,6 @@ class VirtualHost(object): # pylint: disable=too-few-public-methods """ def __init__(self, filep, addrs, ssl, enabled, names, raw, path): - # pylint: disable=too-many-arguments """Initialize a VH.""" self.filep = filep self.addrs = addrs diff --git a/certbot-nginx/certbot_nginx/parser.py b/certbot-nginx/certbot_nginx/_internal/parser.py similarity index 94% rename from certbot-nginx/certbot_nginx/parser.py rename to certbot-nginx/certbot_nginx/_internal/parser.py index d50606fc5..edb77a1c1 100644 --- a/certbot-nginx/certbot_nginx/parser.py +++ b/certbot-nginx/certbot_nginx/_internal/parser.py @@ -4,16 +4,19 @@ import functools import glob import logging import re -import pyparsing +import pyparsing 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 Tuple # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import Union # pylint: disable=unused-import, no-name-in-module from certbot import errors from certbot.compat import os - -from certbot_nginx import obj -from certbot_nginx import nginxparser -from acme.magic_typing import Union, Dict, Set, Any, List, Tuple # pylint: disable=unused-import, no-name-in-module +from certbot_nginx._internal import nginxparser +from certbot_nginx._internal import obj logger = logging.getLogger(__name__) @@ -129,7 +132,7 @@ class NginxParser(object): Technically this is a misnomer because Nginx does not have virtual hosts, it has 'server blocks'. - :returns: List of :class:`~certbot_nginx.obj.VirtualHost` + :returns: List of :class:`~certbot_nginx._internal.obj.VirtualHost` objects found in configuration :rtype: list @@ -262,7 +265,7 @@ class NginxParser(object): def has_ssl_on_directive(self, vhost): """Does vhost have ssl on for all ports? - :param :class:`~certbot_nginx.obj.VirtualHost` vhost: The vhost in question + :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost: The vhost in question :returns: True if 'ssl on' directive is included :rtype: bool @@ -272,7 +275,7 @@ class NginxParser(object): for directive in server: if not directive: continue - elif _is_ssl_on_directive(directive): + if _is_ssl_on_directive(directive): return True return False @@ -288,7 +291,7 @@ class NginxParser(object): ..todo :: Doesn't match server blocks whose server_name directives are split across multiple conf files. - :param :class:`~certbot_nginx.obj.VirtualHost` vhost: The vhost + :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost: The vhost whose information we use to match on :param list directives: The directives to add :param bool insert_at_top: True if the directives need to be inserted at the top @@ -310,7 +313,7 @@ class NginxParser(object): ..todo :: Doesn't match server blocks whose server_name directives are split across multiple conf files. - :param :class:`~certbot_nginx.obj.VirtualHost` vhost: The vhost + :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost: The vhost whose information we use to match on :param list directives: The directives to add :param bool insert_at_top: True if the directives need to be inserted at the top @@ -323,7 +326,7 @@ class NginxParser(object): def remove_server_directives(self, vhost, directive_name, match_func=None): """Remove all directives of type directive_name. - :param :class:`~certbot_nginx.obj.VirtualHost` vhost: The vhost + :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost: The vhost to remove directives from :param string directive_name: The directive type to remove :param callable match_func: Function of the directive that returns true for directives @@ -359,7 +362,7 @@ class NginxParser(object): only_directives=None): """Duplicate the vhost in the configuration files. - :param :class:`~certbot_nginx.obj.VirtualHost` vhost_template: The vhost + :param :class:`~certbot_nginx._internal.obj.VirtualHost` vhost_template: The vhost whose information we copy :param bool remove_singleton_listen_params: If we should remove parameters from listen directives in the block that can only be used once per address @@ -367,7 +370,7 @@ class NginxParser(object): looks at first level of depth; does not expand includes. :returns: A vhost object for the newly created vhost - :rtype: :class:`~certbot_nginx.obj.VirtualHost` + :rtype: :class:`~certbot_nginx._internal.obj.VirtualHost` """ # TODO: https://github.com/certbot/certbot/issues/5185 # put it in the same file as the template, at the same level @@ -486,7 +489,7 @@ def get_best_match(target_name, names): def _exact_match(target_name, name): - return target_name == name or '.' + target_name == name + return name in (target_name, '.' + target_name) def _wildcard_match(target_name, name, start): @@ -504,7 +507,7 @@ def _wildcard_match(target_name, name, start): # The first part must be a wildcard or blank, e.g. '.eff.org' first = match_parts.pop(0) - if first != '*' and first != '': + if first not in ('*', ''): return False target_name = '.'.join(parts) @@ -582,7 +585,7 @@ def comment_directive(block, location): if isinstance(next_entry, list) and next_entry: if len(next_entry) >= 2 and next_entry[-2] == "#" and COMMENT in next_entry[-1]: return - elif isinstance(next_entry, nginxparser.UnspacedList): + if isinstance(next_entry, nginxparser.UnspacedList): next_entry = next_entry.spaced[0] else: next_entry = next_entry[0] @@ -658,13 +661,12 @@ def _add_directive(block, directive, insert_at_top): for included_directive in included_directives: included_dir_loc = _find_location(block, included_directive[0]) included_dir_name = included_directive[0] - if not _is_whitespace_or_comment(included_directive) \ - and not can_append(included_dir_loc, included_dir_name): + if (not _is_whitespace_or_comment(included_directive) + and not can_append(included_dir_loc, included_dir_name)): if block[included_dir_loc] != included_directive: raise errors.MisconfigurationError(err_fmt.format(included_directive, block[included_dir_loc])) - else: - _comment_out_directive(block, included_dir_loc, directive[1]) + _comment_out_directive(block, included_dir_loc, directive[1]) if can_append(location, directive_name): if insert_at_top: diff --git a/certbot-nginx/certbot_nginx/parser_obj.py b/certbot-nginx/certbot_nginx/_internal/parser_obj.py similarity index 99% rename from certbot-nginx/certbot_nginx/parser_obj.py rename to certbot-nginx/certbot_nginx/_internal/parser_obj.py index 71e8c6088..e03913887 100644 --- a/certbot-nginx/certbot_nginx/parser_obj.py +++ b/certbot-nginx/certbot_nginx/_internal/parser_obj.py @@ -3,12 +3,12 @@ raw lists of tokens from pyparsing. """ import abc import logging + import six +from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module from certbot import errors -from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - logger = logging.getLogger(__name__) COMMENT = " managed by Certbot" COMMENT_BLOCK = ["#", COMMENT] diff --git a/certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx-old.conf b/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx-old.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx-old.conf rename to certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx-old.conf diff --git a/certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx-tls12-only.conf b/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx-tls12-only.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx-tls12-only.conf rename to certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx-tls12-only.conf diff --git a/certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx-tls13-session-tix-on.conf b/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx-tls13-session-tix-on.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx-tls13-session-tix-on.conf rename to certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx-tls13-session-tix-on.conf diff --git a/certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx.conf b/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx.conf rename to certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf diff --git a/certbot-nginx/certbot_nginx/tests/__init__.py b/certbot-nginx/certbot_nginx/tests/__init__.py deleted file mode 100644 index 32ca193d9..000000000 --- a/certbot-nginx/certbot_nginx/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Certbot Nginx Tests""" diff --git a/certbot-nginx/docs/.gitignore b/certbot-nginx/docs/.gitignore deleted file mode 100644 index ba65b13af..000000000 --- a/certbot-nginx/docs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/_build/ diff --git a/certbot-nginx/docs/Makefile b/certbot-nginx/docs/Makefile deleted file mode 100644 index 0bd88a347..000000000 --- a/certbot-nginx/docs/Makefile +++ /dev/null @@ -1,192 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/certbot-nginx.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/certbot-nginx.qhc" - -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/certbot-nginx" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/certbot-nginx" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/certbot-nginx/docs/_static/.gitignore b/certbot-nginx/docs/_static/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/certbot-nginx/docs/_templates/.gitignore b/certbot-nginx/docs/_templates/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/certbot-nginx/docs/api.rst b/certbot-nginx/docs/api.rst deleted file mode 100644 index 8668ec5d8..000000000 --- a/certbot-nginx/docs/api.rst +++ /dev/null @@ -1,8 +0,0 @@ -================= -API Documentation -================= - -.. toctree:: - :glob: - - api/** diff --git a/certbot-nginx/docs/api/nginxparser.rst b/certbot-nginx/docs/api/nginxparser.rst deleted file mode 100644 index 6a3be5247..000000000 --- a/certbot-nginx/docs/api/nginxparser.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_nginx.nginxparser` ------------------------------------- - -.. automodule:: certbot_nginx.nginxparser - :members: diff --git a/certbot-nginx/docs/api/obj.rst b/certbot-nginx/docs/api/obj.rst deleted file mode 100644 index a2c94037b..000000000 --- a/certbot-nginx/docs/api/obj.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_nginx.obj` ----------------------------- - -.. automodule:: certbot_nginx.obj - :members: diff --git a/certbot-nginx/docs/api/parser.rst b/certbot-nginx/docs/api/parser.rst deleted file mode 100644 index 0149f99cb..000000000 --- a/certbot-nginx/docs/api/parser.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot_nginx.parser` -------------------------------- - -.. automodule:: certbot_nginx.parser - :members: diff --git a/certbot-nginx/docs/conf.py b/certbot-nginx/docs/conf.py deleted file mode 100644 index d606b6292..000000000 --- a/certbot-nginx/docs/conf.py +++ /dev/null @@ -1,311 +0,0 @@ -# -*- coding: utf-8 -*- -# -# certbot-nginx documentation build configuration file, created by -# sphinx-quickstart on Sun Oct 18 13:39:39 2015. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -from certbot.compat import os -import shlex - - -here = os.path.abspath(os.path.dirname(__file__)) - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath(os.path.join(here, '..'))) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.viewcode', -] - -autodoc_member_order = 'bysource' -autodoc_default_flags = ['show-inheritance', 'private-members'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'certbot-nginx' -copyright = u'2014-2015, Let\'s Encrypt Project' -author = u'Let\'s Encrypt Project' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0' -# The full version, including alpha/beta/rc tags. -release = '0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = 'en' - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -default_role = 'py:obj' - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. - -# http://docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs -# on_rtd is whether we are on readthedocs.org -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' -if not on_rtd: # only import and set the theme if we're building docs locally - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -# otherwise, readthedocs.org uses their theme by default, so no need to specify it - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'certbot-nginxdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - #'preamble': '', - - # Latex figure (float) alignment - #'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'certbot-nginx.tex', u'certbot-nginx Documentation', - u'Let\'s Encrypt Project', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'certbot-nginx', u'certbot-nginx Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'certbot-nginx', u'certbot-nginx Documentation', - author, 'certbot-nginx', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - - -intersphinx_mapping = { - 'python': ('https://docs.python.org/', None), - 'acme': ('https://acme-python.readthedocs.org/en/latest/', None), - 'certbot': ('https://certbot.eff.org/docs/', None), -} diff --git a/certbot-nginx/docs/index.rst b/certbot-nginx/docs/index.rst deleted file mode 100644 index 488a7ab9c..000000000 --- a/certbot-nginx/docs/index.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. certbot-nginx documentation master file, created by - sphinx-quickstart on Sun Oct 18 13:39:39 2015. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to certbot-nginx's documentation! -============================================= - -Contents: - -.. toctree:: - :maxdepth: 2 - - -.. toctree:: - :maxdepth: 1 - - api - - -.. automodule:: certbot_nginx - :members: - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/certbot-nginx/docs/make.bat b/certbot-nginx/docs/make.bat deleted file mode 100644 index b12255d4c..000000000 --- a/certbot-nginx/docs/make.bat +++ /dev/null @@ -1,263 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - echo. coverage to run coverage check of the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -REM Check if sphinx-build is available and fallback to Python version if any -%SPHINXBUILD% 2> nul -if errorlevel 9009 goto sphinx_python -goto sphinx_ok - -:sphinx_python - -set SPHINXBUILD=python -m sphinx.__init__ -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -:sphinx_ok - - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\certbot-nginx.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\certbot-nginx.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "coverage" ( - %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage - if errorlevel 1 exit /b 1 - echo. - echo.Testing of coverage in the sources finished, look at the ^ -results in %BUILDDIR%/coverage/python.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/certbot-nginx/local-oldest-requirements.txt b/certbot-nginx/local-oldest-requirements.txt index 3192f8360..cee142934 100644 --- a/certbot-nginx/local-oldest-requirements.txt +++ b/certbot-nginx/local-oldest-requirements.txt @@ -1,3 +1,3 @@ # Remember to update setup.py to match the package versions below. --e acme[dev] --e .[dev] +acme[dev]==1.0.0 +certbot[dev]==1.1.0 diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 50febc33a..eb6961729 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -1,16 +1,16 @@ -from setuptools import setup -from setuptools import find_packages -from setuptools.command.test import test as TestCommand import sys +from setuptools import find_packages +from setuptools import setup +from setuptools.command.test import test as TestCommand -version = '1.0.0.dev0' +version = '1.2.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=1.0.0.dev0', - 'certbot>=1.0.0.dev0', + 'acme>=1.0.0', + 'certbot>=1.0.0', 'mock', 'PyOpenSSL', 'pyparsing>=1.5.5', # Python3 support; perhaps unnecessary? @@ -18,11 +18,6 @@ install_requires = [ 'zope.interface', ] -docs_extras = [ - 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags - 'sphinx_rtd_theme', -] - class PyTest(TestCommand): user_options = [] @@ -74,12 +69,9 @@ setup( packages=find_packages(), include_package_data=True, install_requires=install_requires, - extras_require={ - 'docs': docs_extras, - }, entry_points={ 'certbot.plugins': [ - 'nginx = certbot_nginx.configurator:NginxConfigurator', + 'nginx = certbot_nginx._internal.configurator:NginxConfigurator', ], }, test_suite='certbot_nginx', diff --git a/certbot-nginx/certbot_nginx/tests/configurator_test.py b/certbot-nginx/tests/configurator_test.py similarity index 93% rename from certbot-nginx/certbot_nginx/tests/configurator_test.py rename to certbot-nginx/tests/configurator_test.py index 237e22d8f..ef5593395 100644 --- a/certbot-nginx/certbot_nginx/tests/configurator_test.py +++ b/certbot-nginx/tests/configurator_test.py @@ -1,23 +1,21 @@ -# pylint: disable=too-many-public-methods -"""Test for certbot_nginx.configurator.""" +"""Test for certbot_nginx._internal.configurator.""" import unittest -import OpenSSL import mock +import OpenSSL + from acme import challenges from acme import messages - from certbot import achallenges from certbot import crypto_util from certbot import errors from certbot.compat import os from certbot.tests import util as certbot_test_util - -from certbot_nginx import obj -from certbot_nginx import parser -from certbot_nginx.configurator import _redirect_block_for_domain -from certbot_nginx.nginxparser import UnspacedList -from certbot_nginx.tests import util +from certbot_nginx._internal import obj +from certbot_nginx._internal import parser +from certbot_nginx._internal.configurator import _redirect_block_for_domain +from certbot_nginx._internal.nginxparser import UnspacedList +import test_util as util class NginxConfiguratorTest(util.NginxTest): @@ -27,10 +25,10 @@ class NginxConfiguratorTest(util.NginxTest): def setUp(self): super(NginxConfiguratorTest, self).setUp() - self.config = util.get_nginx_configurator( + self.config = self.get_nginx_configurator( self.config_path, self.config_dir, self.work_dir, self.logs_dir) - @mock.patch("certbot_nginx.configurator.util.exe_exists") + @mock.patch("certbot_nginx._internal.configurator.util.exe_exists") def test_prepare_no_install(self, mock_exe_exists): mock_exe_exists.return_value = False self.assertRaises( @@ -40,8 +38,8 @@ class NginxConfiguratorTest(util.NginxTest): self.assertEqual((1, 6, 2), self.config.version) self.assertEqual(11, len(self.config.parser.parsed)) - @mock.patch("certbot_nginx.configurator.util.exe_exists") - @mock.patch("certbot_nginx.configurator.subprocess.Popen") + @mock.patch("certbot_nginx._internal.configurator.util.exe_exists") + @mock.patch("certbot_nginx._internal.configurator.subprocess.Popen") def test_prepare_initializes_version(self, mock_popen, mock_exe_exists): mock_popen().communicate.return_value = ( "", "\n".join(["nginx version: nginx/1.6.2", @@ -67,7 +65,7 @@ class NginxConfiguratorTest(util.NginxTest): self.config.config_test = mock.Mock() certbot_test_util.lock_and_call(self._test_prepare_locked, server_root) - @mock.patch("certbot_nginx.configurator.util.exe_exists") + @mock.patch("certbot_nginx._internal.configurator.util.exe_exists") def _test_prepare_locked(self, unused_exe_exists): try: self.config.prepare() @@ -78,7 +76,7 @@ class NginxConfiguratorTest(util.NginxTest): else: # pragma: no cover self.fail("Exception wasn't raised!") - @mock.patch("certbot_nginx.configurator.socket.gethostbyaddr") + @mock.patch("certbot_nginx._internal.configurator.socket.gethostbyaddr") def test_get_all_names(self, mock_gethostbyaddr): mock_gethostbyaddr.return_value = ('155.225.50.69.nephoscale.net', [], []) names = self.config.get_all_names() @@ -218,7 +216,7 @@ class NginxConfiguratorTest(util.NginxTest): "example/chain.pem", None) - @mock.patch('certbot_nginx.parser.NginxParser.update_or_add_server_directives') + @mock.patch('certbot_nginx._internal.parser.NginxParser.update_or_add_server_directives') def test_deploy_cert_raise_on_add_error(self, mock_update_or_add_server_directives): mock_update_or_add_server_directives.side_effect = errors.MisconfigurationError() self.assertRaises( @@ -316,9 +314,9 @@ class NginxConfiguratorTest(util.NginxTest): ]], parsed_migration_conf[0]) - @mock.patch("certbot_nginx.configurator.http_01.NginxHttp01.perform") - @mock.patch("certbot_nginx.configurator.NginxConfigurator.restart") - @mock.patch("certbot_nginx.configurator.NginxConfigurator.revert_challenge_config") + @mock.patch("certbot_nginx._internal.configurator.http_01.NginxHttp01.perform") + @mock.patch("certbot_nginx._internal.configurator.NginxConfigurator.restart") + @mock.patch("certbot_nginx._internal.configurator.NginxConfigurator.revert_challenge_config") def test_perform_and_cleanup(self, mock_revert, mock_restart, mock_http_perform): # Only tests functionality specific to configurator.perform # Note: As more challenges are offered this will have to be expanded @@ -344,7 +342,7 @@ class NginxConfiguratorTest(util.NginxTest): self.assertEqual(mock_revert.call_count, 1) self.assertEqual(mock_restart.call_count, 2) - @mock.patch("certbot_nginx.configurator.subprocess.Popen") + @mock.patch("certbot_nginx._internal.configurator.subprocess.Popen") def test_get_version(self, mock_popen): mock_popen().communicate.return_value = ( "", "\n".join(["nginx version: nginx/1.4.2", @@ -394,7 +392,7 @@ class NginxConfiguratorTest(util.NginxTest): mock_popen.side_effect = OSError("Can't find program") self.assertRaises(errors.PluginError, self.config.get_version) - @mock.patch("certbot_nginx.configurator.subprocess.Popen") + @mock.patch("certbot_nginx._internal.configurator.subprocess.Popen") def test_get_openssl_version(self, mock_popen): # pylint: disable=protected-access mock_popen().communicate.return_value = ( @@ -456,21 +454,21 @@ class NginxConfiguratorTest(util.NginxTest): """) self.assertEqual(self.config._get_openssl_version(), "") - @mock.patch("certbot_nginx.configurator.subprocess.Popen") + @mock.patch("certbot_nginx._internal.configurator.subprocess.Popen") def test_nginx_restart(self, mock_popen): mocked = mock_popen() mocked.communicate.return_value = ('', '') mocked.returncode = 0 self.config.restart() - @mock.patch("certbot_nginx.configurator.subprocess.Popen") + @mock.patch("certbot_nginx._internal.configurator.subprocess.Popen") def test_nginx_restart_fail(self, mock_popen): mocked = mock_popen() mocked.communicate.return_value = ('', '') mocked.returncode = 1 self.assertRaises(errors.MisconfigurationError, self.config.restart) - @mock.patch("certbot_nginx.configurator.subprocess.Popen") + @mock.patch("certbot_nginx._internal.configurator.subprocess.Popen") def test_no_nginx_start(self, mock_popen): mock_popen.side_effect = OSError("Can't find program") self.assertRaises(errors.MisconfigurationError, self.config.restart) @@ -624,20 +622,20 @@ class NginxConfiguratorTest(util.NginxTest): "ensure-http-header", "Strict-Transport-Security") - @mock.patch('certbot_nginx.obj.VirtualHost.contains_list') + @mock.patch('certbot_nginx._internal.obj.VirtualHost.contains_list') def test_certbot_redirect_exists(self, mock_contains_list): # Test that we add no redirect statement if there is already a # redirect in the block that is managed by certbot # Has a certbot redirect mock_contains_list.return_value = True - with mock.patch("certbot_nginx.configurator.logger") as mock_logger: + with mock.patch("certbot_nginx._internal.configurator.logger") as mock_logger: self.config.enhance("www.example.com", "redirect") self.assertEqual(mock_logger.info.call_args[0][0], "Traffic on port %s already redirecting to ssl in %s") def test_redirect_dont_enhance(self): # Test that we don't accidentally add redirect to ssl-only block - with mock.patch("certbot_nginx.configurator.logger") as mock_logger: + with mock.patch("certbot_nginx._internal.configurator.logger") as mock_logger: self.config.enhance("geese.com", "redirect") self.assertEqual(mock_logger.info.call_args[0][0], 'No matching insecure server blocks listening on port %s found.') @@ -828,7 +826,7 @@ class NginxConfiguratorTest(util.NginxTest): self.assertTrue(util.contains_at_depth(generated_conf, expected, 2)) @mock.patch('certbot.reverter.logger') - @mock.patch('certbot_nginx.parser.NginxParser.load') + @mock.patch('certbot_nginx._internal.parser.NginxParser.load') def test_parser_reload_after_config_changes(self, mock_parser_load, unused_mock_logger): self.config.recovery_routine() self.config.revert_challenge_config() @@ -837,7 +835,7 @@ class NginxConfiguratorTest(util.NginxTest): def test_choose_vhosts_wildcard(self): # pylint: disable=protected-access - mock_path = "certbot_nginx.display_ops.select_vhost_multiple" + mock_path = "certbot_nginx._internal.display_ops.select_vhost_multiple" with mock.patch(mock_path) as mock_select_vhs: vhost = [x for x in self.config.parser.get_vhosts() if 'summer.com' in x.names][0] @@ -853,7 +851,7 @@ class NginxConfiguratorTest(util.NginxTest): def test_choose_vhosts_wildcard_redirect(self): # pylint: disable=protected-access - mock_path = "certbot_nginx.display_ops.select_vhost_multiple" + mock_path = "certbot_nginx._internal.display_ops.select_vhost_multiple" with mock.patch(mock_path) as mock_select_vhs: vhost = [x for x in self.config.parser.get_vhosts() if 'summer.com' in x.names][0] @@ -874,7 +872,7 @@ class NginxConfiguratorTest(util.NginxTest): if 'geese.com' in x.names][0] mock_choose_vhosts.return_value = [vhost] self.config._choose_vhosts_wildcard = mock_choose_vhosts - mock_d = "certbot_nginx.configurator.NginxConfigurator._deploy_cert" + mock_d = "certbot_nginx._internal.configurator.NginxConfigurator._deploy_cert" with mock.patch(mock_d) as mock_dep: self.config.deploy_cert("*.com", "/tmp/path", "/tmp/path", "/tmp/path", "/tmp/path") @@ -882,7 +880,7 @@ class NginxConfiguratorTest(util.NginxTest): self.assertEqual(len(mock_dep.call_args_list), 1) self.assertEqual(vhost, mock_dep.call_args_list[0][0][0]) - @mock.patch("certbot_nginx.display_ops.select_vhost_multiple") + @mock.patch("certbot_nginx._internal.display_ops.select_vhost_multiple") def test_deploy_cert_wildcard_no_vhosts(self, mock_dialog): # pylint: disable=protected-access mock_dialog.return_value = [] @@ -891,7 +889,7 @@ class NginxConfiguratorTest(util.NginxTest): "*.wild.cat", "/tmp/path", "/tmp/path", "/tmp/path", "/tmp/path") - @mock.patch("certbot_nginx.display_ops.select_vhost_multiple") + @mock.patch("certbot_nginx._internal.display_ops.select_vhost_multiple") def test_enhance_wildcard_ocsp_after_install(self, mock_dialog): # pylint: disable=protected-access vhost = [x for x in self.config.parser.get_vhosts() @@ -900,7 +898,7 @@ class NginxConfiguratorTest(util.NginxTest): self.config.enhance("*.com", "staple-ocsp", "example/chain.pem") self.assertFalse(mock_dialog.called) - @mock.patch("certbot_nginx.display_ops.select_vhost_multiple") + @mock.patch("certbot_nginx._internal.display_ops.select_vhost_multiple") def test_enhance_wildcard_redirect_or_ocsp_no_install(self, mock_dialog): vhost = [x for x in self.config.parser.get_vhosts() if 'summer.com' in x.names][0] @@ -908,7 +906,7 @@ class NginxConfiguratorTest(util.NginxTest): self.config.enhance("*.com", "staple-ocsp", "example/chain.pem") self.assertTrue(mock_dialog.called) - @mock.patch("certbot_nginx.display_ops.select_vhost_multiple") + @mock.patch("certbot_nginx._internal.display_ops.select_vhost_multiple") def test_enhance_wildcard_double_redirect(self, mock_dialog): # pylint: disable=protected-access vhost = [x for x in self.config.parser.get_vhosts() @@ -919,7 +917,7 @@ class NginxConfiguratorTest(util.NginxTest): def test_choose_vhosts_wildcard_no_ssl_filter_port(self): # pylint: disable=protected-access - mock_path = "certbot_nginx.display_ops.select_vhost_multiple" + mock_path = "certbot_nginx._internal.display_ops.select_vhost_multiple" with mock.patch(mock_path) as mock_select_vhs: mock_select_vhs.return_value = [] self.config._choose_vhosts_wildcard("*.com", @@ -935,7 +933,7 @@ class InstallSslOptionsConfTest(util.NginxTest): def setUp(self): super(InstallSslOptionsConfTest, self).setUp() - self.config = util.get_nginx_configurator( + self.config = self.get_nginx_configurator( self.config_path, self.config_dir, self.work_dir, self.logs_dir) def _call(self): @@ -975,14 +973,14 @@ class InstallSslOptionsConfTest(util.NginxTest): return _hash def test_prev_file_updates_to_current(self): - from certbot_nginx.constants import ALL_SSL_OPTIONS_HASHES + from certbot_nginx._internal.constants import ALL_SSL_OPTIONS_HASHES with mock.patch('certbot.crypto_util.sha256sum', new=self._mock_hash_except_ssl_conf_src(ALL_SSL_OPTIONS_HASHES[0])): self._call() self._assert_current_file() def test_prev_file_updates_to_current_old_nginx(self): - from certbot_nginx.constants import ALL_SSL_OPTIONS_HASHES + from certbot_nginx._internal.constants import ALL_SSL_OPTIONS_HASHES self.config.version = (1, 5, 8) with mock.patch('certbot.crypto_util.sha256sum', new=self._mock_hash_except_ssl_conf_src(ALL_SSL_OPTIONS_HASHES[0])): @@ -1019,7 +1017,7 @@ class InstallSslOptionsConfTest(util.NginxTest): self.assertFalse(mock_logger.warning.called) def test_current_file_hash_in_all_hashes(self): - from certbot_nginx.constants import ALL_SSL_OPTIONS_HASHES + from certbot_nginx._internal.constants import ALL_SSL_OPTIONS_HASHES self.assertTrue(self._current_ssl_options_hash() in ALL_SSL_OPTIONS_HASHES, "Constants.ALL_SSL_OPTIONS_HASHES must be appended" " with the sha256 hash of self.config.mod_ssl_conf when it is updated.") @@ -1031,10 +1029,11 @@ class InstallSslOptionsConfTest(util.NginxTest): file has been manually edited by the user, and will refuse to update it. This test ensures that all necessary hashes are present. """ - from certbot_nginx.constants import ALL_SSL_OPTIONS_HASHES + from certbot_nginx._internal.constants import ALL_SSL_OPTIONS_HASHES import pkg_resources all_files = [ - pkg_resources.resource_filename("certbot_nginx", os.path.join("tls_configs", x)) + pkg_resources.resource_filename("certbot_nginx", + os.path.join("_internal", "tls_configs", x)) for x in ("options-ssl-nginx.conf", "options-ssl-nginx-old.conf", "options-ssl-nginx-tls12-only.conf") @@ -1071,10 +1070,10 @@ class InstallSslOptionsConfTest(util.NginxTest): class DetermineDefaultServerRootTest(certbot_test_util.ConfigTestCase): - """Tests for certbot_nginx.configurator._determine_default_server_root.""" + """Tests for certbot_nginx._internal.configurator._determine_default_server_root.""" def _call(self): - from certbot_nginx.configurator import _determine_default_server_root + from certbot_nginx._internal.configurator import _determine_default_server_root return _determine_default_server_root() @mock.patch.dict(os.environ, {"CERTBOT_DOCS": "1"}) @@ -1092,7 +1091,7 @@ class DetermineDefaultServerRootTest(certbot_test_util.ConfigTestCase): self.assertIn("/usr/local/etc/nginx", server_root) self.assertIn("/etc/nginx", server_root) else: - self.assertTrue(server_root == "/etc/nginx" or server_root == "/usr/local/etc/nginx") + self.assertTrue(server_root in ("/etc/nginx", "/usr/local/etc/nginx")) if __name__ == "__main__": diff --git a/certbot-nginx/certbot_nginx/tests/display_ops_test.py b/certbot-nginx/tests/display_ops_test.py similarity index 83% rename from certbot-nginx/certbot_nginx/tests/display_ops_test.py rename to certbot-nginx/tests/display_ops_test.py index e3c6fb66b..377255441 100644 --- a/certbot-nginx/certbot_nginx/tests/display_ops_test.py +++ b/certbot-nginx/tests/display_ops_test.py @@ -1,18 +1,15 @@ -"""Test certbot_apache.display_ops.""" +"""Test certbot_nginx._internal.display_ops.""" import unittest from certbot.display import util as display_util - from certbot.tests import util as certbot_util - -from certbot_nginx import parser - -from certbot_nginx.display_ops import select_vhost_multiple -from certbot_nginx.tests import util +from certbot_nginx._internal import parser +from certbot_nginx._internal.display_ops import select_vhost_multiple +import test_util as util class SelectVhostMultiTest(util.NginxTest): - """Tests for certbot_nginx.display_ops.select_vhost_multiple.""" + """Tests for certbot_nginx._internal.display_ops.select_vhost_multiple.""" def setUp(self): super(SelectVhostMultiTest, self).setUp() diff --git a/certbot-nginx/certbot_nginx/tests/http_01_test.py b/certbot-nginx/tests/http_01_test.py similarity index 86% rename from certbot-nginx/certbot_nginx/tests/http_01_test.py rename to certbot-nginx/tests/http_01_test.py index c6d35b808..6418a8841 100644 --- a/certbot-nginx/certbot_nginx/tests/http_01_test.py +++ b/certbot-nginx/tests/http_01_test.py @@ -1,24 +1,24 @@ -"""Tests for certbot_nginx.http_01""" +"""Tests for certbot_nginx._internal.http_01""" import unittest +import josepy as jose import mock import six from acme import challenges - from certbot import achallenges - -from certbot.plugins import common_test from certbot.tests import acme_util +from certbot.tests import util as test_util +from certbot_nginx._internal.obj import Addr +import test_util as util -from certbot_nginx.obj import Addr -from certbot_nginx.tests import util +AUTH_KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem")) class HttpPerformTest(util.NginxTest): """Test the NginxHttp01 challenge.""" - account_key = common_test.AUTH_KEY + account_key = AUTH_KEY achalls = [ achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.chall_to_challb( @@ -47,17 +47,17 @@ class HttpPerformTest(util.NginxTest): def setUp(self): super(HttpPerformTest, self).setUp() - config = util.get_nginx_configurator( + config = self.get_nginx_configurator( self.config_path, self.config_dir, self.work_dir, self.logs_dir) - from certbot_nginx import http_01 + from certbot_nginx._internal import http_01 self.http01 = http_01.NginxHttp01(config) def test_perform0(self): responses = self.http01.perform() self.assertEqual([], responses) - @mock.patch("certbot_nginx.configurator.NginxConfigurator.save") + @mock.patch("certbot_nginx._internal.configurator.NginxConfigurator.save") def test_perform1(self, mock_save): self.http01.add_chall(self.achalls[0]) response = self.achalls[0].response(self.account_key) @@ -103,7 +103,7 @@ class HttpPerformTest(util.NginxTest): # self.assertEqual(vhost.addrs, set(v_addr2_print)) # self.assertEqual(vhost.names, set([response.z_domain.decode('ascii')])) - @mock.patch("certbot_nginx.configurator.NginxConfigurator.ipv6_info") + @mock.patch("certbot_nginx._internal.configurator.NginxConfigurator.ipv6_info") def test_default_listen_addresses_no_memoization(self, ipv6_info): # pylint: disable=protected-access ipv6_info.return_value = (True, True) @@ -113,7 +113,7 @@ class HttpPerformTest(util.NginxTest): self.http01._default_listen_addresses() self.assertEqual(ipv6_info.call_count, 2) - @mock.patch("certbot_nginx.configurator.NginxConfigurator.ipv6_info") + @mock.patch("certbot_nginx._internal.configurator.NginxConfigurator.ipv6_info") def test_default_listen_addresses_t_t(self, ipv6_info): # pylint: disable=protected-access ipv6_info.return_value = (True, True) @@ -122,7 +122,7 @@ class HttpPerformTest(util.NginxTest): http_ipv6_addr = Addr.fromstring("[::]:80") self.assertEqual(addrs, [http_addr, http_ipv6_addr]) - @mock.patch("certbot_nginx.configurator.NginxConfigurator.ipv6_info") + @mock.patch("certbot_nginx._internal.configurator.NginxConfigurator.ipv6_info") def test_default_listen_addresses_t_f(self, ipv6_info): # pylint: disable=protected-access ipv6_info.return_value = (True, False) @@ -131,7 +131,7 @@ class HttpPerformTest(util.NginxTest): http_ipv6_addr = Addr.fromstring("[::]:80 ipv6only=on") self.assertEqual(addrs, [http_addr, http_ipv6_addr]) - @mock.patch("certbot_nginx.configurator.NginxConfigurator.ipv6_info") + @mock.patch("certbot_nginx._internal.configurator.NginxConfigurator.ipv6_info") def test_default_listen_addresses_f_f(self, ipv6_info): # pylint: disable=protected-access ipv6_info.return_value = (False, False) diff --git a/certbot-nginx/certbot_nginx/tests/nginxparser_test.py b/certbot-nginx/tests/nginxparser_test.py similarity index 97% rename from certbot-nginx/certbot_nginx/tests/nginxparser_test.py rename to certbot-nginx/tests/nginxparser_test.py index 7fc4576c3..a5212078f 100644 --- a/certbot-nginx/certbot_nginx/tests/nginxparser_test.py +++ b/certbot-nginx/tests/nginxparser_test.py @@ -1,4 +1,4 @@ -"""Test for certbot_nginx.nginxparser.""" +"""Test for certbot_nginx._internal.nginxparser.""" import copy import operator import tempfile @@ -6,10 +6,13 @@ import unittest from pyparsing import ParseException -from certbot_nginx.nginxparser import ( - RawNginxParser, loads, load, dumps, dump, UnspacedList) -from certbot_nginx.tests import util - +from certbot_nginx._internal.nginxparser import dump +from certbot_nginx._internal.nginxparser import dumps +from certbot_nginx._internal.nginxparser import load +from certbot_nginx._internal.nginxparser import loads +from certbot_nginx._internal.nginxparser import RawNginxParser +from certbot_nginx._internal.nginxparser import UnspacedList +import test_util as util FIRST = operator.itemgetter(0) diff --git a/certbot-nginx/certbot_nginx/tests/obj_test.py b/certbot-nginx/tests/obj_test.py similarity index 92% rename from certbot-nginx/certbot_nginx/tests/obj_test.py rename to certbot-nginx/tests/obj_test.py index 9e5853c4a..db808229f 100644 --- a/certbot-nginx/certbot_nginx/tests/obj_test.py +++ b/certbot-nginx/tests/obj_test.py @@ -1,12 +1,12 @@ -"""Test the helper objects in certbot_nginx.obj.""" -import unittest +"""Test the helper objects in certbot_nginx._internal.obj.""" import itertools +import unittest class AddrTest(unittest.TestCase): """Test the Addr class.""" def setUp(self): - from certbot_nginx.obj import Addr + from certbot_nginx._internal.obj import Addr self.addr1 = Addr.fromstring("192.168.1.1") self.addr2 = Addr.fromstring("192.168.1.1:* ssl") self.addr3 = Addr.fromstring("192.168.1.1:80") @@ -71,14 +71,14 @@ class AddrTest(unittest.TestCase): self.assertEqual(self.addr6.to_string(include_default=False), "80") def test_eq(self): - from certbot_nginx.obj import Addr + from certbot_nginx._internal.obj import Addr new_addr1 = Addr.fromstring("192.168.1.1 spdy") self.assertEqual(self.addr1, new_addr1) self.assertNotEqual(self.addr1, self.addr2) self.assertFalse(self.addr1 == 3333) def test_equivalent_any_addresses(self): - from certbot_nginx.obj import Addr + from certbot_nginx._internal.obj import Addr any_addresses = ("0.0.0.0:80 default_server ssl", "80 default_server ssl", "*:80 default_server ssl", @@ -97,7 +97,7 @@ class AddrTest(unittest.TestCase): Addr.fromstring(any_address)) def test_set_inclusion(self): - from certbot_nginx.obj import Addr + from certbot_nginx._internal.obj import Addr set_a = set([self.addr1, self.addr2]) addr1b = Addr.fromstring("192.168.1.1") addr2b = Addr.fromstring("192.168.1.1:* ssl") @@ -109,8 +109,8 @@ class AddrTest(unittest.TestCase): class VirtualHostTest(unittest.TestCase): """Test the VirtualHost class.""" def setUp(self): - from certbot_nginx.obj import VirtualHost - from certbot_nginx.obj import Addr + from certbot_nginx._internal.obj import VirtualHost + from certbot_nginx._internal.obj import Addr raw1 = [ ['listen', '69.50.225.155:9000'], [['if', '($scheme', '!=', '"https") '], @@ -159,8 +159,8 @@ class VirtualHostTest(unittest.TestCase): set(['localhost']), raw_has_hsts, []) def test_eq(self): - from certbot_nginx.obj import Addr - from certbot_nginx.obj import VirtualHost + from certbot_nginx._internal.obj import Addr + from certbot_nginx._internal.obj import VirtualHost vhost1b = VirtualHost( "filep", set([Addr.fromstring("localhost blah")]), False, False, @@ -183,9 +183,9 @@ class VirtualHostTest(unittest.TestCase): self.assertFalse(self.vhost1.has_header('Bogus-Header')) def test_contains_list(self): - from certbot_nginx.obj import VirtualHost - from certbot_nginx.obj import Addr - from certbot_nginx.configurator import _test_block_from_block + from certbot_nginx._internal.obj import VirtualHost + from certbot_nginx._internal.obj import Addr + from certbot_nginx._internal.configurator import _test_block_from_block test_block = [ ['\n ', 'return', ' ', '301', ' ', 'https://$host$request_uri'], ['\n'] diff --git a/certbot-nginx/certbot_nginx/tests/parser_obj_test.py b/certbot-nginx/tests/parser_obj_test.py similarity index 92% rename from certbot-nginx/certbot_nginx/tests/parser_obj_test.py rename to certbot-nginx/tests/parser_obj_test.py index 2217be54f..132f83771 100644 --- a/certbot-nginx/certbot_nginx/tests/parser_obj_test.py +++ b/certbot-nginx/tests/parser_obj_test.py @@ -1,20 +1,22 @@ """ Tests for functions and classes in parser_obj.py """ import unittest + import mock -from certbot_nginx.parser_obj import parse_raw -from certbot_nginx.parser_obj import COMMENT_BLOCK +from certbot_nginx._internal.parser_obj import COMMENT_BLOCK +from certbot_nginx._internal.parser_obj import parse_raw + class CommentHelpersTest(unittest.TestCase): def test_is_comment(self): - from certbot_nginx.parser_obj import _is_comment + from certbot_nginx._internal.parser_obj import _is_comment self.assertTrue(_is_comment(parse_raw(['#']))) self.assertTrue(_is_comment(parse_raw(['#', ' literally anything else']))) self.assertFalse(_is_comment(parse_raw(['not', 'even', 'a', 'comment']))) def test_is_certbot_comment(self): - from certbot_nginx.parser_obj import _is_certbot_comment + from certbot_nginx._internal.parser_obj import _is_certbot_comment self.assertTrue(_is_certbot_comment( parse_raw(COMMENT_BLOCK))) self.assertFalse(_is_certbot_comment( @@ -25,7 +27,7 @@ class CommentHelpersTest(unittest.TestCase): parse_raw(['not', 'even', 'a', 'comment']))) def test_certbot_comment(self): - from certbot_nginx.parser_obj import _certbot_comment, _is_certbot_comment + from certbot_nginx._internal.parser_obj import _certbot_comment, _is_certbot_comment comment = _certbot_comment(None) self.assertTrue(_is_certbot_comment(comment)) self.assertEqual(comment.dump(), COMMENT_BLOCK) @@ -35,7 +37,7 @@ class CommentHelpersTest(unittest.TestCase): class ParsingHooksTest(unittest.TestCase): def test_is_sentence(self): - from certbot_nginx.parser_obj import Sentence + from certbot_nginx._internal.parser_obj import Sentence self.assertFalse(Sentence.should_parse([])) self.assertTrue(Sentence.should_parse([''])) self.assertTrue(Sentence.should_parse(['word'])) @@ -44,7 +46,7 @@ class ParsingHooksTest(unittest.TestCase): self.assertFalse(Sentence.should_parse(['word', []])) def test_is_block(self): - from certbot_nginx.parser_obj import Block + from certbot_nginx._internal.parser_obj import Block self.assertFalse(Block.should_parse([])) self.assertFalse(Block.should_parse([''])) self.assertFalse(Block.should_parse(['two', 'words'])) @@ -71,7 +73,7 @@ class ParsingHooksTest(unittest.TestCase): fake_parser1.not_called() fake_parser2.called_once() - @mock.patch("certbot_nginx.parser_obj.Parsable.parsing_hooks") + @mock.patch("certbot_nginx._internal.parser_obj.Parsable.parsing_hooks") def test_parse_raw_no_match(self, parsing_hooks): from certbot import errors fake_parser1 = mock.Mock() @@ -91,7 +93,7 @@ class ParsingHooksTest(unittest.TestCase): class SentenceTest(unittest.TestCase): def setUp(self): - from certbot_nginx.parser_obj import Sentence + from certbot_nginx._internal.parser_obj import Sentence self.sentence = Sentence(None) def test_parse_bad_sentence_raises_error(self): @@ -137,7 +139,7 @@ class SentenceTest(unittest.TestCase): class BlockTest(unittest.TestCase): def setUp(self): - from certbot_nginx.parser_obj import Block + from certbot_nginx._internal.parser_obj import Block self.bloc = Block(None) self.name = ['server', 'name'] self.contents = [['thing', '1'], ['thing', '2'], ['another', 'one']] @@ -153,7 +155,7 @@ class BlockTest(unittest.TestCase): def test_iterate_match(self): # can match on contents while expanded - from certbot_nginx.parser_obj import Block, Sentence + from certbot_nginx._internal.parser_obj import Block, Sentence expected = [['thing', '1'], ['thing', '2']] for i, elem in enumerate(self.bloc.iterate(expanded=True, match=lambda x: isinstance(x, Sentence) and 'thing' in x.words)): @@ -192,7 +194,7 @@ class BlockTest(unittest.TestCase): class StatementsTest(unittest.TestCase): def setUp(self): - from certbot_nginx.parser_obj import Statements + from certbot_nginx._internal.parser_obj import Statements self.statements = Statements(None) self.raw = [ ['sentence', 'one'], diff --git a/certbot-nginx/certbot_nginx/tests/parser_test.py b/certbot-nginx/tests/parser_test.py similarity index 94% rename from certbot-nginx/certbot_nginx/tests/parser_test.py rename to certbot-nginx/tests/parser_test.py index 396f996bf..2f3b260ca 100644 --- a/certbot-nginx/certbot_nginx/tests/parser_test.py +++ b/certbot-nginx/tests/parser_test.py @@ -1,21 +1,19 @@ -"""Tests for certbot_nginx.parser.""" +"""Tests for certbot_nginx._internal.parser.""" import glob import re import shutil import unittest from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - from certbot import errors from certbot.compat import os - -from certbot_nginx import nginxparser -from certbot_nginx import obj -from certbot_nginx import parser -from certbot_nginx.tests import util +from certbot_nginx._internal import nginxparser +from certbot_nginx._internal import obj +from certbot_nginx._internal import parser +import test_util as util -class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods +class NginxParserTest(util.NginxTest): """Nginx Parser Test.""" def tearDown(self): @@ -51,16 +49,16 @@ class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods """ nparser = parser.NginxParser(self.config_path) nparser.load() - self.assertEqual(set([nparser.abs_path(x) for x in - ['foo.conf', 'nginx.conf', 'server.conf', - 'sites-enabled/default', - 'sites-enabled/example.com', - 'sites-enabled/headers.com', - 'sites-enabled/migration.com', - 'sites-enabled/sslon.com', - 'sites-enabled/globalssl.com', - 'sites-enabled/ipv6.com', - 'sites-enabled/ipv6ssl.com']]), + self.assertEqual({nparser.abs_path(x) for x in + ['foo.conf', 'nginx.conf', 'server.conf', + 'sites-enabled/default', + 'sites-enabled/example.com', + 'sites-enabled/headers.com', + 'sites-enabled/migration.com', + 'sites-enabled/sslon.com', + 'sites-enabled/globalssl.com', + 'sites-enabled/ipv6.com', + 'sites-enabled/ipv6ssl.com']}, set(nparser.parsed.keys())) self.assertEqual([['server_name', 'somename', 'alias', 'another.alias']], nparser.parsed[nparser.abs_path('server.conf')]) @@ -253,7 +251,7 @@ class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods [['foo', 'bar'], ['ssl_certificate', '/etc/ssl/cert2.pem']]) nparser.add_server_directives(mock_vhost, [['foo', 'bar']]) - from certbot_nginx.parser import COMMENT + from certbot_nginx._internal.parser import COMMENT self.assertEqual(nparser.parsed[example_com], [[['server'], [['listen', '69.50.225.155:9000'], ['listen', '127.0.0.1'], @@ -288,7 +286,7 @@ class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods nparser.add_server_directives(mock_vhost, [['\n ', 'include', ' ', nparser.abs_path('comment_in_file.conf')]]) - from certbot_nginx.parser import COMMENT + from certbot_nginx._internal.parser import COMMENT self.assertEqual(nparser.parsed[example_com], [[['server'], [['listen', '69.50.225.155:9000'], ['listen', '127.0.0.1'], @@ -308,7 +306,7 @@ class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods mock_vhost = obj.VirtualHost(filep, None, None, None, target, None, [0]) nparser.update_or_add_server_directives( mock_vhost, [['server_name', 'foobar.com']]) - from certbot_nginx.parser import COMMENT + from certbot_nginx._internal.parser import COMMENT self.assertEqual( nparser.parsed[filep], [[['server'], [['listen', '69.50.225.155:9000'], @@ -367,7 +365,7 @@ class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods ["\n", "a", " ", "b", "\n"], ["c", " ", "d"], ["\n", "e", " ", "f"]]) - from certbot_nginx.parser import comment_directive, COMMENT_BLOCK + from certbot_nginx._internal.parser import comment_directive, COMMENT_BLOCK comment_directive(block, 1) comment_directive(block, 0) self.assertEqual(block.spaced, [ @@ -391,7 +389,7 @@ class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods ssl_prefer_server_ciphers on; }""") block = server_block[0][1] - from certbot_nginx.parser import _comment_out_directive + from certbot_nginx._internal.parser import _comment_out_directive _comment_out_directive(block, 4, "blah1") _comment_out_directive(block, 5, "blah2") _comment_out_directive(block, 6, "blah3") diff --git a/certbot-nginx/certbot_nginx/tests/util.py b/certbot-nginx/tests/test_util.py similarity index 60% rename from certbot-nginx/certbot_nginx/tests/util.py rename to certbot-nginx/tests/test_util.py index c0a70368e..8dfd18637 100644 --- a/certbot-nginx/certbot_nginx/tests/util.py +++ b/certbot-nginx/tests/test_util.py @@ -2,30 +2,30 @@ import copy import shutil import tempfile -import unittest import josepy as jose import mock import pkg_resources import zope.component -from certbot import configuration from certbot import util from certbot.compat import os from certbot.plugins import common from certbot.tests import util as test_util - -from certbot_nginx import configurator -from certbot_nginx import nginxparser +from certbot_nginx._internal import configurator +from certbot_nginx._internal import nginxparser -class NginxTest(unittest.TestCase): # pylint: disable=too-few-public-methods +class NginxTest(test_util.ConfigTestCase): def setUp(self): super(NginxTest, self).setUp() + self.configuration = self.config + self.config = None + self.temp_dir, self.config_dir, self.work_dir = common.dir_setup( - "etc_nginx", "certbot_nginx.tests") + "etc_nginx", __name__) self.logs_dir = tempfile.mkdtemp('logs') self.config_path = os.path.join(self.temp_dir, "etc_nginx") @@ -45,51 +45,49 @@ class NginxTest(unittest.TestCase): # pylint: disable=too-few-public-methods shutil.rmtree(self.work_dir) shutil.rmtree(self.logs_dir) + def get_nginx_configurator(self, config_path, config_dir, work_dir, logs_dir, + version=(1, 6, 2), openssl_version="1.0.2g"): + """Create an Nginx Configurator with the specified options.""" + + backups = os.path.join(work_dir, "backups") + + self.configuration.nginx_server_root = config_path + self.configuration.le_vhost_ext = "-le-ssl.conf" + self.configuration.config_dir = config_dir + self.configuration.work_dir = work_dir + self.configuration.logs_dir = logs_dir + self.configuration.backup_dir = backups + self.configuration.temp_checkpoint_dir = os.path.join(work_dir, "temp_checkpoints") + self.configuration.in_progress_dir = os.path.join(backups, "IN_PROGRESS") + self.configuration.server = "https://acme-server.org:443/new" + self.configuration.http01_port = 80 + self.configuration.https_port = 5001 + + with mock.patch("certbot_nginx._internal.configurator.NginxConfigurator." + "config_test"): + with mock.patch("certbot_nginx._internal.configurator.util." + "exe_exists") as mock_exe_exists: + mock_exe_exists.return_value = True + config = configurator.NginxConfigurator( + self.configuration, + name="nginx", + version=version, + openssl_version=openssl_version) + config.prepare() + + # Provide general config utility. + zope.component.provideUtility(self.configuration) + + return config + def get_data_filename(filename): """Gets the filename of a test data file.""" return pkg_resources.resource_filename( - "certbot_nginx.tests", os.path.join( + __name__, os.path.join( "testdata", "etc_nginx", filename)) -def get_nginx_configurator( - config_path, config_dir, work_dir, logs_dir, version=(1, 6, 2), openssl_version="1.0.2g"): - """Create an Nginx Configurator with the specified options.""" - - backups = os.path.join(work_dir, "backups") - - with mock.patch("certbot_nginx.configurator.NginxConfigurator." - "config_test"): - with mock.patch("certbot_nginx.configurator.util." - "exe_exists") as mock_exe_exists: - mock_exe_exists.return_value = True - config = configurator.NginxConfigurator( - config=mock.MagicMock( - nginx_server_root=config_path, - le_vhost_ext="-le-ssl.conf", - config_dir=config_dir, - work_dir=work_dir, - logs_dir=logs_dir, - backup_dir=backups, - temp_checkpoint_dir=os.path.join(work_dir, "temp_checkpoints"), - in_progress_dir=os.path.join(backups, "IN_PROGRESS"), - server="https://acme-server.org:443/new", - http01_port=80, - https_port=5001, - ), - name="nginx", - version=version, - openssl_version=openssl_version) - config.prepare() - - # Provide general config utility. - nsconfig = configuration.NamespaceConfig(config.config) - zope.component.provideUtility(nsconfig) - - return config - - def filter_comments(tree): """Filter comment nodes from parsed configurations.""" diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/broken.conf b/certbot-nginx/tests/testdata/etc_nginx/broken.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/broken.conf rename to certbot-nginx/tests/testdata/etc_nginx/broken.conf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/comment_in_file.conf b/certbot-nginx/tests/testdata/etc_nginx/comment_in_file.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/comment_in_file.conf rename to certbot-nginx/tests/testdata/etc_nginx/comment_in_file.conf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/edge_cases.conf b/certbot-nginx/tests/testdata/etc_nginx/edge_cases.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/edge_cases.conf rename to certbot-nginx/tests/testdata/etc_nginx/edge_cases.conf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/foo.conf b/certbot-nginx/tests/testdata/etc_nginx/foo.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/foo.conf rename to certbot-nginx/tests/testdata/etc_nginx/foo.conf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/mime.types b/certbot-nginx/tests/testdata/etc_nginx/mime.types similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/mime.types rename to certbot-nginx/tests/testdata/etc_nginx/mime.types diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/minimalistic_comments.conf b/certbot-nginx/tests/testdata/etc_nginx/minimalistic_comments.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/minimalistic_comments.conf rename to certbot-nginx/tests/testdata/etc_nginx/minimalistic_comments.conf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/multiline_quotes.conf b/certbot-nginx/tests/testdata/etc_nginx/multiline_quotes.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/multiline_quotes.conf rename to certbot-nginx/tests/testdata/etc_nginx/multiline_quotes.conf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/nginx.conf b/certbot-nginx/tests/testdata/etc_nginx/nginx.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/nginx.conf rename to certbot-nginx/tests/testdata/etc_nginx/nginx.conf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/server.conf b/certbot-nginx/tests/testdata/etc_nginx/server.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/server.conf rename to certbot-nginx/tests/testdata/etc_nginx/server.conf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/default b/certbot-nginx/tests/testdata/etc_nginx/sites-enabled/default similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/default rename to certbot-nginx/tests/testdata/etc_nginx/sites-enabled/default diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/example.com b/certbot-nginx/tests/testdata/etc_nginx/sites-enabled/example.com similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/example.com rename to certbot-nginx/tests/testdata/etc_nginx/sites-enabled/example.com diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/globalssl.com b/certbot-nginx/tests/testdata/etc_nginx/sites-enabled/globalssl.com similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/globalssl.com rename to certbot-nginx/tests/testdata/etc_nginx/sites-enabled/globalssl.com diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/headers.com b/certbot-nginx/tests/testdata/etc_nginx/sites-enabled/headers.com similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/headers.com rename to certbot-nginx/tests/testdata/etc_nginx/sites-enabled/headers.com diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/ipv6.com b/certbot-nginx/tests/testdata/etc_nginx/sites-enabled/ipv6.com similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/ipv6.com rename to certbot-nginx/tests/testdata/etc_nginx/sites-enabled/ipv6.com diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/ipv6ssl.com b/certbot-nginx/tests/testdata/etc_nginx/sites-enabled/ipv6ssl.com similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/ipv6ssl.com rename to certbot-nginx/tests/testdata/etc_nginx/sites-enabled/ipv6ssl.com diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/migration.com b/certbot-nginx/tests/testdata/etc_nginx/sites-enabled/migration.com similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/migration.com rename to certbot-nginx/tests/testdata/etc_nginx/sites-enabled/migration.com diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/sslon.com b/certbot-nginx/tests/testdata/etc_nginx/sites-enabled/sslon.com similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/sites-enabled/sslon.com rename to certbot-nginx/tests/testdata/etc_nginx/sites-enabled/sslon.com diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/fastcgi_params b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/fastcgi_params similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/fastcgi_params rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/fastcgi_params diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-utf b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-utf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-utf rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-utf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-win b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-win similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-win rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-win diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/mime.types b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/mime.types similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/mime.types rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/mime.types diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi-ui.conf.1.4.1 b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi-ui.conf.1.4.1 similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi-ui.conf.1.4.1 rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi-ui.conf.1.4.1 diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi.rules b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi.rules similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi.rules rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi.rules diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi_core.rules b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi_core.rules similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi_core.rules rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi_core.rules diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/nginx.conf b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/nginx.conf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/nginx.conf rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/nginx.conf diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/proxy_params b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/proxy_params similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/proxy_params rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/proxy_params diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/scgi_params b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/scgi_params similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/scgi_params rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/scgi_params diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-available/default b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-available/default similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-available/default rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-available/default diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-enabled/default b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-enabled/default similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-enabled/default rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-enabled/default diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/uwsgi_params b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/uwsgi_params similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/uwsgi_params rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/uwsgi_params diff --git a/certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/win-utf b/certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/win-utf similarity index 100% rename from certbot-nginx/certbot_nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/win-utf rename to certbot-nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/win-utf diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md new file mode 100644 index 000000000..dd70000cd --- /dev/null +++ b/certbot/CHANGELOG.md @@ -0,0 +1,1898 @@ +# Certbot change log + +Certbot adheres to [Semantic Versioning](https://semver.org/). + +## 1.2.0 - master + +### Added + +* + +### Changed + +* Add directory field to error message when field is missing. + +### Fixed + +* + +More details about these changes can be found on our GitHub repo. + +## 1.1.0 - 2020-01-14 + +### Added + +* + +### Changed + +* Removed the fallback introduced with 0.34.0 in `acme` to retry a POST-as-GET + request as a GET request when the targeted ACME CA server seems to not support + POST-as-GET requests. +* certbot-auto no longer supports architectures other than x86_64 on RHEL 6 + based systems. Existing certbot-auto installations affected by this will + continue to work, but they will no longer receive updates. To install a + newer version of Certbot on these systems, you should update your OS. +* Support for Python 3.4 in Certbot and its ACME library is deprecated and will be + removed in the next release of Certbot. certbot-auto users on x86_64 systems running + RHEL 6 or derivatives will be asked to enable Software Collections (SCL) repository + so Python 3.6 can be installed. certbot-auto can enable the SCL repo for you on CentOS 6 + while users on other RHEL 6 based systems will be asked to do this manually. + +### Fixed + +* + +More details about these changes can be found on our GitHub repo. + +## 1.0.0 - 2019-12-03 + +### Added + +* + +### Removed + +* The `docs` extras for the `certbot-apache` and `certbot-nginx` packages + have been removed. + +### Changed + +* certbot-auto has deprecated support for systems using OpenSSL 1.0.1 that are + not running on x86-64. This primarily affects RHEL 6 based systems. +* Certbot's `config_changes` subcommand has been removed +* `certbot.plugins.common.TLSSNI01` has been removed. +* Deprecated attributes related to the TLS-SNI-01 challenge in + `acme.challenges` and `acme.standalone` + have been removed. +* The functions `certbot.client.view_config_changes`, + `certbot.main.config_changes`, + `certbot.plugins.common.Installer.view_config_changes`, + `certbot.reverter.Reverter.view_config_changes`, and + `certbot.util.get_systemd_os_info` have been removed +* Certbot's `register --update-registration` subcommand has been removed +* When possible, default to automatically configuring the webserver so all requests + redirect to secure HTTPS access. This is mostly relevant when running Certbot + in non-interactive mode. Previously, the default was to not redirect all requests. + +### Fixed + +* + +More details about these changes can be found on our GitHub repo. + +## 0.40.1 - 2019-11-05 + +### Changed + +* Added back support for Python 3.4 to Certbot components and certbot-auto due + to a bug when requiring Python 2.7 or 3.5+ on RHEL 6 based systems. + +More details about these changes can be found on our GitHub repo. + +## 0.40.0 - 2019-11-05 + +### Added + +* + +### Changed + +* We deprecated support for Python 3.4 in Certbot and its ACME library. Support + for Python 3.4 will be removed in the next major release of Certbot. + certbot-auto users on RHEL 6 based systems will be asked to enable Software + Collections (SCL) repository so Python 3.6 can be installed. certbot-auto can + enable the SCL repo for you on CentOS 6 while users on other RHEL 6 based + systems will be asked to do this manually. +* `--server` may now be combined with `--dry-run`. Certbot will, as before, use the + staging server instead of the live server when `--dry-run` is used. +* `--dry-run` now requests fresh authorizations every time, fixing the issue + where it was prone to falsely reporting success. +* Updated certbot-dns-google to depend on newer versions of + google-api-python-client and oauth2client. +* The OS detection logic again uses distro library for Linux OSes +* certbot.plugins.common.TLSSNI01 has been deprecated and will be removed in a + future release. +* CLI flags --tls-sni-01-port and --tls-sni-01-address have been removed. +* The values tls-sni and tls-sni-01 for the --preferred-challenges flag are no + longer accepted. +* Removed the flags: `--agree-dev-preview`, `--dialog`, and `--apache-init-script` +* acme.standalone.BaseRequestHandlerWithLogging and + acme.standalone.simple_tls_sni_01_server have been deprecated and will be + removed in a future release of the library. +* certbot-dns-rfc2136 now use TCP to query SOA records. + +### Fixed + +* + +More details about these changes can be found on our GitHub repo. + +## 0.39.0 - 2019-10-01 + +### Added + +* Support for Python 3.8 was added to Certbot and all of its components. +* Support for CentOS 8 was added to certbot-auto. + +### Changed + +* Don't send OCSP requests for expired certificates +* Return to using platform.linux_distribution instead of distro.linux_distribution in OS fingerprinting for Python < 3.8 +* Updated the Nginx plugin's TLS configuration to keep support for some versions of IE11. + +### Fixed + +* Fixed OS detection in the Apache plugin on RHEL 6. + +More details about these changes can be found on our GitHub repo. + +## 0.38.0 - 2019-09-03 + +### Added + +* Disable session tickets for Nginx users when appropriate. + +### Changed + +* If Certbot fails to rollback your server configuration, the error message + links to the Let's Encrypt forum. Change the link to the Help category now + that the Server category has been closed. +* Replace platform.linux_distribution with distro.linux_distribution as a step + towards Python 3.8 support in Certbot. + +### Fixed + +* Fixed OS detection in the Apache plugin on Scientific Linux. + +More details about these changes can be found on our GitHub repo. + +## 0.37.2 - 2019-08-21 + +* Stop disabling TLS session tickets in Nginx as it caused TLS failures on + some systems. + +More details about these changes can be found on our GitHub repo. + +## 0.37.1 - 2019-08-08 + +### Fixed + +* Stop disabling TLS session tickets in Apache as it caused TLS failures on + some systems. + +More details about these changes can be found on our GitHub repo. + +## 0.37.0 - 2019-08-07 + +### Added + +* Turn off session tickets for apache plugin by default +* acme: Authz deactivation added to `acme` module. + +### Changed + +* Follow updated Mozilla recommendations for Nginx ssl_protocols, ssl_ciphers, + and ssl_prefer_server_ciphers + +### Fixed + +* Fix certbot-auto failures on RHEL 8. + +More details about these changes can be found on our GitHub repo. + +## 0.36.0 - 2019-07-11 + +### Added + +* Turn off session tickets for nginx plugin by default +* Added missing error types from RFC8555 to acme + +### Changed + +* Support for Ubuntu 14.04 Trusty has been removed. +* Update the 'manage your account' help to be more generic. +* The error message when Certbot's Apache plugin is unable to modify your + Apache configuration has been improved. +* Certbot's config_changes subcommand has been deprecated and will be + removed in a future release. +* `certbot config_changes` no longer accepts a --num parameter. +* The functions `certbot.plugins.common.Installer.view_config_changes` and + `certbot.reverter.Reverter.view_config_changes` have been deprecated and will + be removed in a future release. + +### Fixed + +* Replace some unnecessary platform-specific line separation. + +More details about these changes can be found on our GitHub repo. + +## 0.35.1 - 2019-06-10 + +### Fixed + +* Support for specifying an authoritative base domain in our dns-rfc2136 plugin + has been removed. This feature was added in our last release but had a bug + which caused the plugin to fail so the feature has been removed until it can + be added properly. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* certbot-dns-rfc2136 + +More details about these changes can be found on our GitHub repo. + +## 0.35.0 - 2019-06-05 + +### Added + +* dns_rfc2136 plugin now supports explicitly specifing an authorative + base domain for cases when the automatic method does not work (e.g. + Split horizon DNS) + +### Changed + +* + +### Fixed + +* Renewal parameter `webroot_path` is always saved, avoiding some regressions + when `webroot` authenticator plugin is invoked with no challenge to perform. +* Certbot now accepts OCSP responses when an explicit authorized + responder, different from the issuer, is used to sign OCSP + responses. +* Scripts in Certbot hook directories are no longer executed when their + filenames end in a tilde. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* certbot +* certbot-dns-rfc2136 + +More details about these changes can be found on our GitHub repo. + +## 0.34.2 - 2019-05-07 + +### Fixed + +* certbot-auto no longer writes a check_permissions.py script at the root + of the filesystem. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +changes in this release were to certbot-auto. + +More details about these changes can be found on our GitHub repo. + +## 0.34.1 - 2019-05-06 + +### Fixed + +* certbot-auto no longer prints a blank line when there are no permissions + problems. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +changes in this release were to certbot-auto. + +More details about these changes can be found on our GitHub repo. + +## 0.34.0 - 2019-05-01 + +### Changed + +* Apache plugin now tries to restart httpd on Fedora using systemctl if a + configuration test error is detected. This has to be done due to the way + Fedora now generates the self signed certificate files upon first + restart. +* Updated Certbot and its plugins to improve the handling of file system permissions + on Windows as a step towards adding proper Windows support to Certbot. +* Updated urllib3 to 1.24.2 in certbot-auto. +* Removed the fallback introduced with 0.32.0 in `acme` to retry a challenge response + with a `keyAuthorization` if sending the response without this field caused a + `malformed` error to be received from the ACME server. +* Linode DNS plugin now supports api keys created from their new panel + at [cloud.linode.com](https://cloud.linode.com) + +### Fixed + +* Fixed Google DNS Challenge issues when private zones exist +* Adding a warning noting that future versions of Certbot will automatically configure the + webserver so that all requests redirect to secure HTTPS access. You can control this + behavior and disable this warning with the --redirect and --no-redirect flags. +* certbot-auto now prints warnings when run as root with insecure file system + permissions. If you see these messages, you should fix the problem by + following the instructions at + https://community.letsencrypt.org/t/certbot-auto-deployment-best-practices/91979/, + however, these warnings can be disabled as necessary with the flag + --no-permissions-check. +* `acme` module uses now a POST-as-GET request to retrieve the registration + from an ACME v2 server +* Convert the tsig algorithm specified in the certbot_dns_rfc2136 configuration file to + all uppercase letters before validating. This makes the value in the config case + insensitive. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* acme +* certbot +* certbot-apache +* certbot-dns-cloudflare +* certbot-dns-cloudxns +* certbot-dns-digitalocean +* certbot-dns-dnsimple +* certbot-dns-dnsmadeeasy +* certbot-dns-gehirn +* certbot-dns-google +* certbot-dns-linode +* certbot-dns-luadns +* certbot-dns-nsone +* certbot-dns-ovh +* certbot-dns-rfc2136 +* certbot-dns-route53 +* certbot-dns-sakuracloud +* certbot-nginx + +More details about these changes can be found on our GitHub repo. + +## 0.33.1 - 2019-04-04 + +### Fixed + +* A bug causing certbot-auto to print warnings or crash on some RHEL based + systems has been resolved. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +changes in this release were to certbot-auto. + +More details about these changes can be found on our GitHub repo. + +## 0.33.0 - 2019-04-03 + +### Added + +* Fedora 29+ is now supported by certbot-auto. Since Python 2.x is on a deprecation + path in Fedora, certbot-auto will install and use Python 3.x on Fedora 29+. +* CLI flag `--https-port` has been added for Nginx plugin exclusively, and replaces + `--tls-sni-01-port`. It defines the HTTPS port the Nginx plugin will use while + setting up a new SSL vhost. By default the HTTPS port is 443. + +### Changed + +* Support for TLS-SNI-01 has been removed from all official Certbot plugins. +* Attributes related to the TLS-SNI-01 challenge in `acme.challenges` and `acme.standalone` + modules are deprecated and will be removed soon. +* CLI flags `--tls-sni-01-port` and `--tls-sni-01-address` are now no-op, will + generate a deprecation warning if used, and will be removed soon. +* Options `tls-sni` and `tls-sni-01` in `--preferred-challenges` flag are now no-op, + will generate a deprecation warning if used, and will be removed soon. +* CLI flag `--standalone-supported-challenges` has been removed. + +### Fixed + +* Certbot uses the Python library cryptography for OCSP when cryptography>=2.5 + is installed. We fixed a bug in Certbot causing it to interpret timestamps in + the OCSP response as being in the local timezone rather than UTC. +* Issue causing the default CentOS 6 TLS configuration to ignore some of the + HTTPS VirtualHosts created by Certbot. mod_ssl loading is now moved to main + http.conf for this environment where possible. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* acme +* certbot +* certbot-apache +* certbot-nginx + +More details about these changes can be found on our GitHub repo. + +## 0.32.0 - 2019-03-06 + +### Added + +* If possible, Certbot uses built-in support for OCSP from recent cryptography + versions instead of the OpenSSL binary: as a consequence Certbot does not need + the OpenSSL binary to be installed anymore if cryptography>=2.5 is installed. + +### Changed + +* Certbot and its acme module now depend on josepy>=1.1.0 to avoid printing the + warnings described at https://github.com/certbot/josepy/issues/13. +* Apache plugin now respects CERTBOT_DOCS environment variable when adding + command line defaults. +* The running of manual plugin hooks is now always included in Certbot's log + output. +* Tests execution for certbot, certbot-apache and certbot-nginx packages now relies on pytest. +* An ACME CA server may return a "Retry-After" HTTP header on authorization polling, as + specified in the ACME protocol, to indicate when the next polling should occur. Certbot now + reads this header if set and respect its value. +* The `acme` module avoids sending the `keyAuthorization` field in the JWS + payload when responding to a challenge as the field is not included in the + current ACME protocol. To ease the migration path for ACME CA servers, + Certbot and its `acme` module will first try the request without the + `keyAuthorization` field but will temporarily retry the request with the + field included if a `malformed` error is received. This fallback will be + removed in version 0.34.0. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* acme +* certbot +* certbot-apache +* certbot-nginx + +More details about these changes can be found on our GitHub repo. + +## 0.31.0 - 2019-02-07 + +### Added + +* Avoid reprocessing challenges that are already validated + when a certificate is issued. +* Support for initiating (but not solving end-to-end) TLS-ALPN-01 challenges + with the `acme` module. + +### Changed + +* Certbot's official Docker images are now based on Alpine Linux 3.9 rather + than 3.7. The new version comes with OpenSSL 1.1.1. +* Lexicon-based DNS plugins are now fully compatible with Lexicon 3.x (support + on 2.x branch is maintained). +* Apache plugin now attempts to configure all VirtualHosts matching requested + domain name instead of only a single one when answering the HTTP-01 challenge. + +### Fixed + +* Fixed accessing josepy contents through acme.jose when the full acme.jose + path is used. +* Clarify behavior for deleting certs as part of revocation. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* acme +* certbot +* certbot-apache +* certbot-dns-cloudxns +* certbot-dns-dnsimple +* certbot-dns-dnsmadeeasy +* certbot-dns-gehirn +* certbot-dns-linode +* certbot-dns-luadns +* certbot-dns-nsone +* certbot-dns-ovh +* certbot-dns-sakuracloud + +More details about these changes can be found on our GitHub repo. + +## 0.30.2 - 2019-01-25 + +### Fixed + +* Update the version of setuptools pinned in certbot-auto to 40.6.3 to + solve installation problems on newer OSes. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, this +release only affects certbot-auto. + +More details about these changes can be found on our GitHub repo. + +## 0.30.1 - 2019-01-24 + +### Fixed + +* Always download the pinned version of pip in pipstrap to address breakages +* Rename old,default.conf to old-and-default.conf to address commas in filenames + breaking recent versions of pip. +* Add VIRTUALENV_NO_DOWNLOAD=1 to all calls to virtualenv to address breakages + from venv downloading the latest pip + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* certbot-apache + +More details about these changes can be found on our GitHub repo. + +## 0.30.0 - 2019-01-02 + +### Added + +* Added the `update_account` subcommand for account management commands. + +### Changed + +* Copied account management functionality from the `register` subcommand + to the `update_account` subcommand. +* Marked usage `register --update-registration` for deprecation and + removal in a future release. + +### Fixed + +* Older modules in the josepy library can now be accessed through acme.jose + like it could in previous versions of acme. This is only done to preserve + backwards compatibility and support for doing this with new modules in josepy + will not be added. Users of the acme library should switch to using josepy + directly if they haven't done so already. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* acme + +More details about these changes can be found on our GitHub repo. + +## 0.29.1 - 2018-12-05 + +### Added + +* + +### Changed + +* + +### Fixed + +* The default work and log directories have been changed back to + /var/lib/letsencrypt and /var/log/letsencrypt respectively. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* certbot + +More details about these changes can be found on our GitHub repo. + +## 0.29.0 - 2018-12-05 + +### Added + +* Noninteractive renewals with `certbot renew` (those not started from a + terminal) now randomly sleep 1-480 seconds before beginning work in + order to spread out load spikes on the server side. +* Added External Account Binding support in cli and acme library. + Command line arguments --eab-kid and --eab-hmac-key added. + +### Changed + +* Private key permissioning changes: Renewal preserves existing group mode + & gid of previous private key material. Private keys for new + lineages (i.e. new certs, not renewed) default to 0o600. + +### Fixed + +* Update code and dependencies to clean up Resource and Deprecation Warnings. +* Only depend on imgconverter extension for Sphinx >= 1.6 + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* acme +* certbot +* certbot-apache +* certbot-dns-cloudflare +* certbot-dns-digitalocean +* certbot-dns-google +* certbot-nginx + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/62?closed=1 + +## 0.28.0 - 2018-11-7 + +### Added + +* `revoke` accepts `--cert-name`, and doesn't accept both `--cert-name` and `--cert-path`. +* Use the ACMEv2 newNonce endpoint when a new nonce is needed, and newNonce is available in the directory. + +### Changed + +* Removed documentation mentions of `#letsencrypt` IRC on Freenode. +* Write README to the base of (config-dir)/live directory +* `--manual` will explicitly warn users that earlier challenges should remain in place when setting up subsequent challenges. +* Warn when using deprecated acme.challenges.TLSSNI01 +* Log warning about TLS-SNI deprecation in Certbot +* Stop preferring TLS-SNI in the Apache, Nginx, and standalone plugins +* OVH DNS plugin now relies on Lexicon>=2.7.14 to support HTTP proxies +* Default time the Linode plugin waits for DNS changes to propogate is now 1200 seconds. + +### Fixed + +* Match Nginx parser update in allowing variable names to start with `${`. +* Fix ranking of vhosts in Nginx so that all port-matching vhosts come first +* Correct OVH integration tests on machines without internet access. +* Stop caching the results of ipv6_info in http01.py +* Test fix for Route53 plugin to prevent boto3 making outgoing connections. +* The grammar used by Augeas parser in Apache plugin was updated to fix various parsing errors. +* The CloudXNS, DNSimple, DNS Made Easy, Gehirn, Linode, LuaDNS, NS1, OVH, and + Sakura Cloud DNS plugins are now compatible with Lexicon 3.0+. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* acme +* certbot +* certbot-apache +* certbot-dns-cloudxns +* certbot-dns-dnsimple +* certbot-dns-dnsmadeeasy +* certbot-dns-gehirn +* certbot-dns-linode +* certbot-dns-luadns +* certbot-dns-nsone +* certbot-dns-ovh +* certbot-dns-route53 +* certbot-dns-sakuracloud +* certbot-nginx + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/59?closed=1 + +## 0.27.1 - 2018-09-06 + +### Fixed + +* Fixed parameter name in OpenSUSE overrides for default parameters in the + Apache plugin. Certbot on OpenSUSE works again. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* certbot-apache + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/60?closed=1 + +## 0.27.0 - 2018-09-05 + +### Added + +* The Apache plugin now accepts the parameter --apache-ctl which can be + used to configure the path to the Apache control script. + +### Changed + +* When using `acme.client.ClientV2` (or + `acme.client.BackwardsCompatibleClientV2` with an ACME server that supports a + newer version of the ACME protocol), an `acme.errors.ConflictError` will be + raised if you try to create an ACME account with a key that has already been + used. Previously, a JSON parsing error was raised in this scenario when using + the library with Let's Encrypt's ACMEv2 endpoint. + +### Fixed + +* When Apache is not installed, Certbot's Apache plugin no longer prints + messages about being unable to find apachectl to the terminal when the plugin + is not selected. +* If you're using the Apache plugin with the --apache-vhost-root flag set to a + directory containing a disabled virtual host for the domain you're requesting + a certificate for, the virtual host will now be temporarily enabled if + necessary to pass the HTTP challenge. +* The documentation for the Certbot package can now be built using Sphinx 1.6+. +* You can now call `query_registration` without having to first call + `new_account` on `acme.client.ClientV2` objects. +* The requirement of `setuptools>=1.0` has been removed from `certbot-dns-ovh`. +* Names in certbot-dns-sakuracloud's tests have been updated to refer to Sakura + Cloud rather than NS1 whose plugin certbot-dns-sakuracloud was based on. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +package with changes other than its version number was: + +* acme +* certbot +* certbot-apache +* certbot-dns-ovh +* certbot-dns-sakuracloud + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/57?closed=1 + +## 0.26.1 - 2018-07-17 + +### Fixed + +* Fix a bug that was triggered when users who had previously manually set `--server` to get ACMEv2 certs tried to renew ACMEv1 certs. + +Despite us having broken lockstep, we are continuing to release new versions of all Certbot components during releases for the time being, however, the only package with changes other than its version number was: + +* certbot + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/58?closed=1 + +## 0.26.0 - 2018-07-11 + +### Added + +* A new security enhancement which we're calling AutoHSTS has been added to + Certbot's Apache plugin. This enhancement configures your webserver to send a + HTTP Strict Transport Security header with a low max-age value that is slowly + increased over time. The max-age value is not increased to a large value + until you've successfully managed to renew your certificate. This enhancement + can be requested with the --auto-hsts flag. +* New official DNS plugins have been created for Gehirn Infrastracture Service, + Linode, OVH, and Sakura Cloud. These plugins can be found on our Docker Hub + page at https://hub.docker.com/u/certbot and on PyPI. +* The ability to reuse ACME accounts from Let's Encrypt's ACMEv1 endpoint on + Let's Encrypt's ACMEv2 endpoint has been added. +* Certbot and its components now support Python 3.7. +* Certbot's install subcommand now allows you to interactively choose which + certificate to install from the list of certificates managed by Certbot. +* Certbot now accepts the flag `--no-autorenew` which causes any obtained + certificates to not be automatically renewed when it approaches expiration. +* Support for parsing the TLS-ALPN-01 challenge has been added back to the acme + library. + +### Changed + +* Certbot's default ACME server has been changed to Let's Encrypt's ACMEv2 + endpoint. By default, this server will now be used for both new certificate + lineages and renewals. +* The Nginx plugin is no longer marked labeled as an "Alpha" version. +* The `prepare` method of Certbot's plugins is no longer called before running + "Updater" enhancements that are run on every invocation of `certbot renew`. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +packages with functional changes were: + +* acme +* certbot +* certbot-apache +* certbot-dns-gehirn +* certbot-dns-linode +* certbot-dns-ovh +* certbot-dns-sakuracloud +* certbot-nginx + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/55?closed=1 + +## 0.25.1 - 2018-06-13 + +### Fixed + +* TLS-ALPN-01 support has been removed from our acme library. Using our current + dependencies, we are unable to provide a correct implementation of this + challenge so we decided to remove it from the library until we can provide + proper support. +* Issues causing test failures when running the tests in the acme package with + pytest<3.0 has been resolved. +* certbot-nginx now correctly depends on acme>=0.25.0. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +packages with changes other than their version number were: + +* acme +* certbot-nginx + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/56?closed=1 + +## 0.25.0 - 2018-06-06 + +### Added + +* Support for the ready status type was added to acme. Without this change, + Certbot and acme users will begin encountering errors when using Let's + Encrypt's ACMEv2 API starting on June 19th for the staging environment and + July 5th for production. See + https://community.letsencrypt.org/t/acmev2-order-ready-status/62866 for more + information. +* Certbot now accepts the flag --reuse-key which will cause the same key to be + used in the certificate when the lineage is renewed rather than generating a + new key. +* You can now add multiple email addresses to your ACME account with Certbot by + providing a comma separated list of emails to the --email flag. +* Support for Let's Encrypt's upcoming TLS-ALPN-01 challenge was added to acme. + For more information, see + https://community.letsencrypt.org/t/tls-alpn-validation-method/63814/1. +* acme now supports specifying the source address to bind to when sending + outgoing connections. You still cannot specify this address using Certbot. +* If you run Certbot against Let's Encrypt's ACMEv2 staging server but don't + already have an account registered at that server URL, Certbot will + automatically reuse your staging account from Let's Encrypt's ACMEv1 endpoint + if it exists. +* Interfaces were added to Certbot allowing plugins to be called at additional + points. The `GenericUpdater` interface allows plugins to perform actions + every time `certbot renew` is run, regardless of whether any certificates are + due for renewal, and the `RenewDeployer` interface allows plugins to perform + actions when a certificate is renewed. See `certbot.interfaces` for more + information. + +### Changed + +* When running Certbot with --dry-run and you don't already have a staging + account, the created account does not contain an email address even if one + was provided to avoid expiration emails from Let's Encrypt's staging server. +* certbot-nginx does a better job of automatically detecting the location of + Nginx's configuration files when run on BSD based systems. +* acme now requires and uses pytest when running tests with setuptools with + `python setup.py test`. +* `certbot config_changes` no longer waits for user input before exiting. + +### Fixed + +* Misleading log output that caused users to think that Certbot's standalone + plugin failed to bind to a port when performing a challenge has been + corrected. +* An issue where certbot-nginx would fail to enable HSTS if the server block + already had an `add_header` directive has been resolved. +* certbot-nginx now does a better job detecting the server block to base the + configuration for TLS-SNI challenges on. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +packages with functional changes were: + +* acme +* certbot +* certbot-apache +* certbot-nginx + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/54?closed=1 + +## 0.24.0 - 2018-05-02 + +### Added + +* certbot now has an enhance subcommand which allows you to configure security + enhancements like HTTP to HTTPS redirects, OCSP stapling, and HSTS without + reinstalling a certificate. +* certbot-dns-rfc2136 now allows the user to specify the port to use to reach + the DNS server in its credentials file. +* acme now parses the wildcard field included in authorizations so it can be + used by users of the library. + +### Changed + +* certbot-dns-route53 used to wait for each DNS update to propagate before + sending the next one, but now it sends all updates before waiting which + speeds up issuance for multiple domains dramatically. +* Certbot's official Docker images are now based on Alpine Linux 3.7 rather + than 3.4 because 3.4 has reached its end-of-life. +* We've doubled the time Certbot will spend polling authorizations before + timing out. +* The level of the message logged when Certbot is being used with + non-standard paths warning that crontabs for renewal included in Certbot + packages from OS package managers may not work has been reduced. This stops + the message from being written to stderr every time `certbot renew` runs. + +### Fixed + +* certbot-auto now works with Python 3.6. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +packages with changes other than their version number were: + +* acme +* certbot +* certbot-apache +* certbot-dns-digitalocean (only style improvements to tests) +* certbot-dns-rfc2136 + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/52?closed=1 + +## 0.23.0 - 2018-04-04 + +### Added + +* Support for OpenResty was added to the Nginx plugin. + +### Changed + +* The timestamps in Certbot's logfiles now use the system's local time zone + rather than UTC. +* Certbot's DNS plugins that use Lexicon now rely on Lexicon>=2.2.1 to be able + to create and delete multiple TXT records on a single domain. +* certbot-dns-google's test suite now works without an internet connection. + +### Fixed + +* Removed a small window that if during which an error occurred, Certbot + wouldn't clean up performed challenges. +* The parameters `default` and `ipv6only` are now removed from `listen` + directives when creating a new server block in the Nginx plugin. +* `server_name` directives enclosed in quotation marks in Nginx are now properly + supported. +* Resolved an issue preventing the Apache plugin from starting Apache when it's + not currently running on RHEL and Gentoo based systems. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +packages with changes other than their version number were: + +* certbot +* certbot-apache +* certbot-dns-cloudxns +* certbot-dns-dnsimple +* certbot-dns-dnsmadeeasy +* certbot-dns-google +* certbot-dns-luadns +* certbot-dns-nsone +* certbot-dns-rfc2136 +* certbot-nginx + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/50?closed=1 + +## 0.22.2 - 2018-03-19 + +### Fixed + +* A type error introduced in 0.22.1 that would occur during challenge cleanup + when a Certbot plugin raises an exception while trying to complete the + challenge was fixed. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +packages with changes other than their version number were: + +* certbot + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/53?closed=1 + +## 0.22.1 - 2018-03-19 + +### Changed + +* The ACME server used with Certbot's --dry-run and --staging flags is now + Let's Encrypt's ACMEv2 staging server which allows people to also test ACMEv2 + features with these flags. + +### Fixed + +* The HTTP Content-Type header is now set to the correct value during + certificate revocation with new versions of the ACME protocol. +* When using Certbot with Let's Encrypt's ACMEv2 server, it would add a blank + line to the top of chain.pem and between the certificates in fullchain.pem + for each lineage. These blank lines have been removed. +* Resolved a bug that caused Certbot's --allow-subset-of-names flag not to + work. +* Fixed a regression in acme.client.Client that caused the class to not work + when it was initialized without a ClientNetwork which is done by some of the + other projects using our ACME library. + +Despite us having broken lockstep, we are continuing to release new versions of +all Certbot components during releases for the time being, however, the only +packages with changes other than their version number were: + +* acme +* certbot + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/51?closed=1 + +## 0.22.0 - 2018-03-07 + +### Added + +* Support for obtaining wildcard certificates and a newer version of the ACME + protocol such as the one implemented by Let's Encrypt's upcoming ACMEv2 + endpoint was added to Certbot and its ACME library. Certbot still works with + older ACME versions and will automatically change the version of the protocol + used based on the version the ACME CA implements. +* The Apache and Nginx plugins are now able to automatically install a wildcard + certificate to multiple virtual hosts that you select from your server + configuration. +* The `certbot install` command now accepts the `--cert-name` flag for + selecting a certificate. +* `acme.client.BackwardsCompatibleClientV2` was added to Certbot's ACME library + which automatically handles most of the differences between new and old ACME + versions. `acme.client.ClientV2` is also available for people who only want + to support one version of the protocol or want to handle the differences + between versions themselves. +* certbot-auto now supports the flag --install-only which has the script + install Certbot and its dependencies and exit without invoking Certbot. +* Support for issuing a single certificate for a wildcard and base domain was + added to our Google Cloud DNS plugin. To do this, we now require your API + credentials have additional permissions, however, your credentials will + already have these permissions unless you defined a custom role with fewer + permissions than the standard DNS administrator role provided by Google. + These permissions are also only needed for the case described above so it + will continue to work for existing users. For more information about the + permissions changes, see the documentation in the plugin. + +### Changed + +* We have broken lockstep between our ACME library, Certbot, and its plugins. + This means that the different components do not need to be the same version + to work together like they did previously. This makes packaging easier + because not every piece of Certbot needs to be repackaged to ship a change to + a subset of its components. +* Support for Python 2.6 and Python 3.3 has been removed from ACME, Certbot, + Certbot's plugins, and certbot-auto. If you are using certbot-auto on a RHEL + 6 based system, it will walk you through the process of installing Certbot + with Python 3 and refuse to upgrade to a newer version of Certbot until you + have done so. +* Certbot's components now work with older versions of setuptools to simplify + packaging for EPEL 7. + +### Fixed + +* Issues caused by Certbot's Nginx plugin adding multiple ipv6only directives + has been resolved. +* A problem where Certbot's Apache plugin would add redundant include + directives for the TLS configuration managed by Certbot has been fixed. +* Certbot's webroot plugin now properly deletes any directories it creates. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/48?closed=1 + +## 0.21.1 - 2018-01-25 + +### Fixed + +* When creating an HTTP to HTTPS redirect in Nginx, we now ensure the Host + header of the request is set to an expected value before redirecting users to + the domain found in the header. The previous way Certbot configured Nginx + redirects was a potential security issue which you can read more about at + https://community.letsencrypt.org/t/security-issue-with-redirects-added-by-certbots-nginx-plugin/51493. +* Fixed a problem where Certbot's Apache plugin could fail HTTP-01 challenges + if basic authentication is configured for the domain you request a + certificate for. +* certbot-auto --no-bootstrap now properly tries to use Python 3.4 on RHEL 6 + based systems rather than Python 2.6. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/49?closed=1 + +## 0.21.0 - 2018-01-17 + +### Added + +* Support for the HTTP-01 challenge type was added to our Apache and Nginx + plugins. For those not aware, Let's Encrypt disabled the TLS-SNI-01 challenge + type which was what was previously being used by our Apache and Nginx plugins + last week due to a security issue. For more information about Let's Encrypt's + change, click + [here](https://community.letsencrypt.org/t/2018-01-11-update-regarding-acme-tls-sni-and-shared-hosting-infrastructure/50188). + Our Apache and Nginx plugins will automatically switch to use HTTP-01 so no + changes need to be made to your Certbot configuration, however, you should + make sure your server is accessible on port 80 and isn't behind an external + proxy doing things like redirecting all traffic from HTTP to HTTPS. HTTP to + HTTPS redirects inside Apache and Nginx are fine. +* IPv6 support was added to the Nginx plugin. +* Support for automatically creating server blocks based on the default server + block was added to the Nginx plugin. +* The flags --delete-after-revoke and --no-delete-after-revoke were added + allowing users to control whether the revoke subcommand also deletes the + certificates it is revoking. + +### Changed + +* We deprecated support for Python 2.6 and Python 3.3 in Certbot and its ACME + library. Support for these versions of Python will be removed in the next + major release of Certbot. If you are using certbot-auto on a RHEL 6 based + system, it will guide you through the process of installing Python 3. +* We split our implementation of JOSE (Javascript Object Signing and + Encryption) out of our ACME library and into a separate package named josepy. + This package is available on [PyPI](https://pypi.python.org/pypi/josepy) and + on [GitHub](https://github.com/certbot/josepy). +* We updated the ciphersuites used in Apache to the new [values recommended by + Mozilla](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29). + The major change here is adding ChaCha20 to the list of supported + ciphersuites. + +### Fixed + +* An issue with our Apache plugin on Gentoo due to differences in their + apache2ctl command have been resolved. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/47?closed=1 + +## 0.20.0 - 2017-12-06 + +### Added + +* Certbot's ACME library now recognizes URL fields in challenge objects in + preparation for Let's Encrypt's new ACME endpoint. The value is still + accessible in our ACME library through the name "uri". + +### Changed + +* The Apache plugin now parses some distro specific Apache configuration files + on non-Debian systems allowing it to get a clearer picture on the running + configuration. Internally, these changes were structured so that external + contributors can easily write patches to make the plugin work in new Apache + configurations. +* Certbot better reports network failures by removing information about + connection retries from the error output. +* An unnecessary question when using Certbot's webroot plugin interactively has + been removed. + +### Fixed + +* Certbot's NGINX plugin no longer sometimes incorrectly reports that it was + unable to deploy a HTTP->HTTPS redirect when requesting Certbot to enable a + redirect for multiple domains. +* Problems where the Apache plugin was failing to find directives and + duplicating existing directives on openSUSE have been resolved. +* An issue running the test shipped with Certbot and some our DNS plugins with + older versions of mock have been resolved. +* On some systems, users reported strangely interleaved output depending on + when stdout and stderr were flushed. This problem was resolved by having + Certbot regularly flush these streams. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/44?closed=1 + +## 0.19.0 - 2017-10-04 + +### Added + +* Certbot now has renewal hook directories where executable files can be placed + for Certbot to run with the renew subcommand. Pre-hooks, deploy-hooks, and + post-hooks can be specified in the renewal-hooks/pre, renewal-hooks/deploy, + and renewal-hooks/post directories respectively in Certbot's configuration + directory (which is /etc/letsencrypt by default). Certbot will automatically + create these directories when it is run if they do not already exist. +* After revoking a certificate with the revoke subcommand, Certbot will offer + to delete the lineage associated with the certificate. When Certbot is run + with --non-interactive, it will automatically try to delete the associated + lineage. +* When using Certbot's Google Cloud DNS plugin on Google Compute Engine, you no + longer have to provide a credential file to Certbot if you have configured + sufficient permissions for the instance which Certbot can automatically + obtain using Google's metadata service. + +### Changed + +* When deleting certificates interactively using the delete subcommand, Certbot + will now allow you to select multiple lineages to be deleted at once. +* Certbot's Apache plugin no longer always parses Apache's sites-available on + Debian based systems and instead only parses virtual hosts included in your + Apache configuration. You can provide an additional directory for Certbot to + parse using the command line flag --apache-vhost-root. + +### Fixed + +* The plugins subcommand can now be run without root access. +* certbot-auto now includes a timeout when updating itself so it no longer + hangs indefinitely when it is unable to connect to the external server. +* An issue where Certbot's Apache plugin would sometimes fail to deploy a + certificate on Debian based systems if mod_ssl wasn't already enabled has + been resolved. +* A bug in our Docker image where the certificates subcommand could not report + if certificates maintained by Certbot had been revoked has been fixed. +* Certbot's RFC 2136 DNS plugin (for use with software like BIND) now properly + performs DNS challenges when the domain being verified contains a CNAME + record. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/43?closed=1 + +## 0.18.2 - 2017-09-20 + +### Fixed + +* An issue where Certbot's ACME module would raise an AttributeError trying to + create self-signed certificates when used with pyOpenSSL 17.3.0 has been + resolved. For Certbot users with this version of pyOpenSSL, this caused + Certbot to crash when performing a TLS SNI challenge or when the Nginx plugin + tried to create an SSL server block. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/46?closed=1 + +## 0.18.1 - 2017-09-08 + +### Fixed + +* If certbot-auto was running as an unprivileged user and it upgraded from + 0.17.0 to 0.18.0, it would crash with a permissions error and would need to + be run again to successfully complete the upgrade. This has been fixed and + certbot-auto should upgrade cleanly to 0.18.1. +* Certbot usually uses "certbot-auto" or "letsencrypt-auto" in error messages + and the User-Agent string instead of "certbot" when you are using one of + these wrapper scripts. Proper detection of this was broken with Certbot's new + installation path in /opt in 0.18.0 but this problem has been resolved. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/45?closed=1 + +## 0.18.0 - 2017-09-06 + +### Added + +* The Nginx plugin now configures Nginx to use 2048-bit Diffie-Hellman + parameters. Java 6 clients do not support Diffie-Hellman parameters larger + than 1024 bits, so if you need to support these clients you will need to + manually modify your Nginx configuration after using the Nginx installer. + +### Changed + +* certbot-auto now installs Certbot in directories under `/opt/eff.org`. If you + had an existing installation from certbot-auto, a symlink is created to the + new directory. You can configure certbot-auto to use a different path by + setting the environment variable VENV_PATH. +* The Nginx plugin can now be selected in Certbot's interactive output. +* Output verbosity of renewal failures when running with `--quiet` has been + reduced. +* The default revocation reason shown in Certbot help output now is a human + readable string instead of a numerical code. +* Plugin selection is now included in normal terminal output. + +### Fixed + +* A newer version of ConfigArgParse is now installed when using certbot-auto + causing values set to false in a Certbot INI configuration file to be handled + intuitively. Setting a boolean command line flag to false is equivalent to + not including it in the configuration file at all. +* New naming conventions preventing certbot-auto from installing OS + dependencies on Fedora 26 have been resolved. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/42?closed=1 + +## 0.17.0 - 2017-08-02 + +### Added + +* Support in our nginx plugin for modifying SSL server blocks that do + not contain certificate or key directives. +* A `--max-log-backups` flag to allow users to configure or even completely + disable Certbot's built in log rotation. +* A `--user-agent-comment` flag to allow people who build tools around Certbot + to differentiate their user agent string by adding a comment to its default + value. + +### Changed + +* Due to some awesome work by + [cryptography project](https://github.com/pyca/cryptography), compilation can + now be avoided on most systems when using certbot-auto. This eliminates many + problems people have had in the past such as running out of memory, having + invalid headers/libraries, and changes to the OS packages on their system + after compilation breaking Certbot. +* The `--renew-hook` flag has been hidden in favor of `--deploy-hook`. This new + flag works exactly the same way except it is always run when a certificate is + issued rather than just when it is renewed. +* We have started printing deprecation warnings in certbot-auto for + experimentally supported systems with OS packages available. +* A certificate lineage's name is included in error messages during renewal. + +### Fixed + +* Encoding errors that could occur when parsing error messages from the ACME + server containing Unicode have been resolved. +* certbot-auto no longer prints misleading messages about there being a newer + pip version available when installation fails. +* Certbot's ACME library now properly extracts domains from critical SAN + extensions. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.17.0+is%3Aclosed + +## 0.16.0 - 2017-07-05 + +### Added + +* A plugin for performing DNS challenges using dynamic DNS updates as defined + in RFC 2316. This plugin is packaged separately from Certbot and is available + at https://pypi.python.org/pypi/certbot-dns-rfc2136. It supports Python 2.6, + 2.7, and 3.3+. At this time, there isn't a good way to install this plugin + when using certbot-auto, but this should change in the near future. +* Plugins for performing DNS challenges for the providers + [DNS Made Easy](https://pypi.python.org/pypi/certbot-dns-dnsmadeeasy) and + [LuaDNS](https://pypi.python.org/pypi/certbot-dns-luadns). These plugins are + packaged separately from Certbot and support Python 2.7 and 3.3+. Currently, + there isn't a good way to install these plugins when using certbot-auto, + but that should change soon. +* Support for performing TLS-SNI-01 challenges when using the manual plugin. +* Automatic detection of Arch Linux in the Apache plugin providing better + default settings for the plugin. + +### Changed + +* The text of the interactive question about whether a redirect from HTTP to + HTTPS should be added by Certbot has been rewritten to better explain the + choices to the user. +* Simplified HTTP challenge instructions in the manual plugin. + +### Fixed + +* Problems performing a dry run when using the Nginx plugin have been fixed. +* Resolved an issue where certbot-dns-digitalocean's test suite would sometimes + fail when ran using Python 3. +* On some systems, previous versions of certbot-auto would error out with a + message about a missing hash for setuptools. This has been fixed. +* A bug where Certbot would sometimes not print a space at the end of an + interactive prompt has been resolved. +* Nonfatal tracebacks are no longer shown in rare cases where Certbot + encounters an exception trying to close its TCP connection with the ACME + server. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.16.0+is%3Aclosed + +## 0.15.0 - 2017-06-08 + +### Added + +* Plugins for performing DNS challenges for popular providers. Like the Apache + and Nginx plugins, these plugins are packaged separately and not included in + Certbot by default. So far, we have plugins for + [Amazon Route 53](https://pypi.python.org/pypi/certbot-dns-route53), + [Cloudflare](https://pypi.python.org/pypi/certbot-dns-cloudflare), + [DigitalOcean](https://pypi.python.org/pypi/certbot-dns-digitalocean), and + [Google Cloud](https://pypi.python.org/pypi/certbot-dns-google) which all + work on Python 2.6, 2.7, and 3.3+. Additionally, we have plugins for + [CloudXNS](https://pypi.python.org/pypi/certbot-dns-cloudxns), + [DNSimple](https://pypi.python.org/pypi/certbot-dns-dnsimple), + [NS1](https://pypi.python.org/pypi/certbot-dns-nsone) which work on Python + 2.7 and 3.3+ (and not 2.6). Currently, there isn't a good way to install + these plugins when using `certbot-auto`, but that should change soon. +* IPv6 support in the standalone plugin. When performing a challenge, the + standalone plugin automatically handles listening for IPv4/IPv6 traffic based + on the configuration of your system. +* A mechanism for keeping your Apache and Nginx SSL/TLS configuration up to + date. When the Apache or Nginx plugins are used, they place SSL/TLS + configuration options in the root of Certbot's config directory + (`/etc/letsencrypt` by default). Now when a new version of these plugins run + on your system, they will automatically update the file to the newest + version if it is unmodified. If you manually modified the file, Certbot will + display a warning giving you a path to the updated file which you can use as + a reference to manually update your modified copy. +* `--http-01-address` and `--tls-sni-01-address` flags for controlling the + address Certbot listens on when using the standalone plugin. +* The command `certbot certificates` that lists certificates managed by Certbot + now performs additional validity checks to notify you if your files have + become corrupted. + +### Changed + +* Messages custom hooks print to `stdout` are now displayed by Certbot when not + running in `--quiet` mode. +* `jwk` and `alg` fields in JWS objects have been moved into the protected + header causing Certbot to more closely follow the latest version of the ACME + spec. + +### Fixed + +* Permissions on renewal configuration files are now properly preserved when + they are updated. +* A bug causing Certbot to display strange defaults in its help output when + using Python <= 2.7.4 has been fixed. +* Certbot now properly handles mixed case domain names found in custom CSRs. +* A number of poorly worded prompts and error messages. + +### Removed + +* Support for OpenSSL 1.0.0 in `certbot-auto` has been removed as we now pin a + newer version of `cryptography` which dropped support for this version. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.15.0+is%3Aclosed + +## 0.14.2 - 2017-05-25 + +### Fixed + +* Certbot 0.14.0 included a bug where Certbot would create a temporary log file +(usually in /tmp) if the program exited during argument parsing. If a user +provided -h/--help/help, --version, or an invalid command line argument, +Certbot would create this temporary log file. This was especially bothersome to +certbot-auto users as certbot-auto runs `certbot --version` internally to see +if the script needs to upgrade causing it to create at least one of these files +on every run. This problem has been resolved. + +More details about this change can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.14.2+is%3Aclosed + +## 0.14.1 - 2017-05-16 + +### Fixed + +* Certbot now works with configargparse 0.12.0. +* Issues with the Apache plugin and Augeas 1.7+ have been resolved. +* A problem where the Nginx plugin would fail to install certificates on +systems that had the plugin's SSL/TLS options file from 7+ months ago has been +fixed. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.14.1+is%3Aclosed + +## 0.14.0 - 2017-05-04 + +### Added + +* Python 3.3+ support for all Certbot packages. `certbot-auto` still currently +only supports Python 2, but the `acme`, `certbot`, `certbot-apache`, and +`certbot-nginx` packages on PyPI now fully support Python 2.6, 2.7, and 3.3+. +* Certbot's Apache plugin now handles multiple virtual hosts per file. +* Lockfiles to prevent multiple versions of Certbot running simultaneously. + +### Changed + +* When converting an HTTP virtual host to HTTPS in Apache, Certbot only copies +the virtual host rather than the entire contents of the file it's contained +in. +* The Nginx plugin now includes SSL/TLS directives in a separate file located +in Certbot's configuration directory rather than copying the contents of the +file into every modified `server` block. + +### Fixed + +* Ensure logging is configured before parts of Certbot attempt to log any +messages. +* Support for the `--quiet` flag in `certbot-auto`. +* Reverted a change made in a previous release to make the `acme` and `certbot` +packages always depend on `argparse`. This dependency is conditional again on +the user's Python version. +* Small bugs in the Nginx plugin such as properly handling empty `server` +blocks and setting `server_names_hash_bucket_size` during challenges. + +As always, a more complete list of changes can be found on GitHub: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.14.0+is%3Aclosed + +## 0.13.0 - 2017-04-06 + +### Added + +* `--debug-challenges` now pauses Certbot after setting up challenges for debugging. +* The Nginx parser can now handle all valid directives in configuration files. +* Nginx ciphersuites have changed to Mozilla Intermediate. +* `certbot-auto --no-bootstrap` provides the option to not install OS dependencies. + +### Fixed + +* `--register-unsafely-without-email` now respects `--quiet`. +* Hyphenated renewal parameters are now saved in renewal config files. +* `--dry-run` no longer persists keys and csrs. +* Certbot no longer hangs when trying to start Nginx in Arch Linux. +* Apache rewrite rules no longer double-encode characters. + +A full list of changes is available on GitHub: +https://github.com/certbot/certbot/issues?q=is%3Aissue%20milestone%3A0.13.0%20is%3Aclosed%20 + +## 0.12.0 - 2017-03-02 + +### Added + +* Certbot now allows non-camelcase Apache VirtualHost names. +* Certbot now allows more log messages to be silenced. + +### Fixed + +* Fixed a regression around using `--cert-name` when getting new certificates + +More information about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue%20milestone%3A0.12.0 + +## 0.11.1 - 2017-02-01 + +### Fixed + +* Resolved a problem where Certbot would crash while parsing command line +arguments in some cases. +* Fixed a typo. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/pulls?q=is%3Apr%20milestone%3A0.11.1%20is%3Aclosed + +## 0.11.0 - 2017-02-01 + +### Added + +* When using the standalone plugin while running Certbot interactively +and a required port is bound by another process, Certbot will give you +the option to retry to grab the port rather than immediately exiting. +* You are now able to deactivate your account with the Let's Encrypt +server using the `unregister` subcommand. +* When revoking a certificate using the `revoke` subcommand, you now +have the option to provide the reason the certificate is being revoked +to Let's Encrypt with `--reason`. + +### Changed + +* Providing `--quiet` to `certbot-auto` now silences package manager output. + +### Removed + +* Removed the optional `dnspython` dependency in our `acme` package. +Now the library does not support client side verification of the DNS +challenge. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.11.0+is%3Aclosed + +## 0.10.2 - 2017-01-25 + +### Added + +* If Certbot receives a request with a `badNonce` error, it now +automatically retries the request. Since nonces from Let's Encrypt expire, +this helps people performing the DNS challenge with the `manual` plugin +who may have to wait an extended period of time for their DNS changes to +propagate. + +### Fixed + +* Certbot now saves the `--preferred-challenges` values for renewal. Previously +these values were discarded causing a different challenge type to be used when +renewing certs in some cases. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.2+is%3Aclosed + +## 0.10.1 - 2017-01-13 + +### Fixed + +* Resolve problems where when asking Certbot to update a certificate at +an existing path to include different domain names, the old names would +continue to be used. +* Fix issues successfully running our unit test suite on some systems. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.1+is%3Aclosed + +## 0.10.0 - 2017-01-11 + +## Added + +* Added the ability to customize and automatically complete DNS and HTTP +domain validation challenges with the manual plugin. The flags +`--manual-auth-hook` and `--manual-cleanup-hook` can now be provided +when using the manual plugin to execute commands provided by the user to +perform and clean up challenges provided by the CA. This is best used in +complicated setups where the DNS challenge must be used or Certbot's +existing plugins cannot be used to perform HTTP challenges. For more +information on how this works, see `certbot --help manual`. +* Added a `--cert-name` flag for specifying the name to use for the +certificate in Certbot's configuration directory. Using this flag in +combination with `-d/--domains`, a user can easily request a new +certificate with different domains and save it with the name provided by +`--cert-name`. Additionally, `--cert-name` can be used to select a +certificate with the `certonly` and `run` subcommands so a full list of +domains in the certificate does not have to be provided. +* Added subcommand `certificates` for listing the certificates managed by +Certbot and their properties. +* Added the `delete` subcommand for removing certificates managed by Certbot +from the configuration directory. +* Certbot now supports requesting internationalized domain names (IDNs). +* Hooks provided to Certbot are now saved to be reused during renewal. +If you run Certbot with `--pre-hook`, `--renew-hook`, or `--post-hook` +flags when obtaining a certificate, the provided commands will +automatically be saved and executed again when renewing the certificate. +A pre-hook and/or post-hook can also be given to the `certbot renew` +command either on the command line or in a [configuration +file](https://certbot.eff.org/docs/using.html#configuration-file) to run +an additional command before/after any certificate is renewed. Hooks +will only be run if a certificate is renewed. +* Support Busybox in certbot-auto. + +### Changed + +* Recategorized `-h/--help` output to improve documentation and +discoverability. + +### Removed + +* Removed the ncurses interface. This change solves problems people +were having on many systems, reduces the number of Certbot +dependencies, and simplifies our code. Certbot's only interface now is +the text interface which was available by providing `-t/--text` to +earlier versions of Certbot. + +### Fixed + +* Many small bug fixes. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.10.0is%3Aclosed + +## 0.9.3 - 2016-10-13 + +### Added + +* The Apache plugin uses information about your OS to help determine the +layout of your Apache configuration directory. We added a patch to +ensure this code behaves the same way when testing on different systems +as the tests were failing in some cases. + +### Changed + +* Certbot adopted more conservative behavior about reporting a needed port as +unavailable when using the standalone plugin. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/27?closed=1 + +## 0.9.2 - 2016-10-12 + +### Added + +* Certbot stopped requiring that all possibly required ports are available when +using the standalone plugin. It now only verifies that the ports are available +when they are necessary. + +### Fixed + +* Certbot now verifies that our optional dependencies version matches what is +required by Certbot. +* Certnot now properly copies the `ssl on;` directives as necessary when +performing domain validation in the Nginx plugin. +* Fixed problem where symlinks were becoming files when they were +packaged, causing errors during testing and OS packaging. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/26?closed=1 + +## 0.9.1 - 2016-10-06 + +### Fixed + +* Fixed a bug that was introduced in version 0.9.0 where the command +line flag -q/--quiet wasn't respected in some cases. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/milestone/25?closed=1 + +## 0.9.0 - 2016-10-05 + +### Added + +* Added an alpha version of the Nginx plugin. This plugin fully automates the +process of obtaining and installing certificates with Nginx. +Additionally, it is able to automatically configure security +enhancements such as an HTTP to HTTPS redirect and OCSP stapling. To use +this plugin, you must have the `certbot-nginx` package installed (which +is installed automatically when using `certbot-auto`) and provide +`--nginx` on the command line. This plugin is still in its early stages +so we recommend you use it with some caution and make sure you have a +backup of your Nginx configuration. +* Added support for the `DNS` challenge in the `acme` library and `DNS` in +Certbot's `manual` plugin. This allows you to create DNS records to +prove to Let's Encrypt you control the requested domain name. To use +this feature, include `--manual --preferred-challenges dns` on the +command line. +* Certbot now helps with enabling Extra Packages for Enterprise Linux (EPEL) on +CentOS 6 when using `certbot-auto`. To use `certbot-auto` on CentOS 6, +the EPEL repository has to be enabled. `certbot-auto` will now prompt +users asking them if they would like the script to enable this for them +automatically. This is done without prompting users when using +`letsencrypt-auto` or if `-n/--non-interactive/--noninteractive` is +included on the command line. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.9.0+is%3Aclosed + +## 0.8.1 - 2016-06-14 + +### Added + +* Certbot now preserves a certificate's common name when using `renew`. +* Certbot now saves webroot values for renewal when they are entered interactively. +* Certbot now gracefully reports that the Apache plugin isn't usable when Augeas is not installed. +* Added experimental support for Mageia has been added to `certbot-auto`. + +### Fixed + +* Fixed problems with an invalid user-agent string on OS X. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.8.1+ + +## 0.8.0 - 2016-06-02 + +### Added + +* Added the `register` subcommand which can be used to register an account +with the Let's Encrypt CA. +* You can now run `certbot register --update-registration` to +change the e-mail address associated with your registration. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue+milestone%3A0.8.0+ + +## 0.7.0 - 2016-05-27 + +### Added + +* Added `--must-staple` to request certificates from Let's Encrypt +with the OCSP must staple extension. +* Certbot now automatically configures OSCP stapling for Apache. +* Certbot now allows requesting certificates for domains found in the common name +of a custom CSR. + +### Fixed + +* Fixed a number of miscellaneous bugs + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=milestone%3A0.7.0+is%3Aissue + +## 0.6.0 - 2016-05-12 + +### Added + +* Versioned the datetime dependency in setup.py. + +### Changed + +* Renamed the client from `letsencrypt` to `certbot`. + +### Fixed + +* Fixed a small json deserialization error. +* Certbot now preserves domain order in generated CSRs. +* Fixed some minor bugs. + +More details about these changes can be found on our GitHub repo: +https://github.com/certbot/certbot/issues?q=is%3Aissue%20milestone%3A0.6.0%20is%3Aclosed%20 + +## 0.5.0 - 2016-04-05 + +### Added + +* Added the ability to use the webroot plugin interactively. +* Added the flags --pre-hook, --post-hook, and --renew-hook which can be used with +the renew subcommand to register shell commands to run in response to +renewal events. Pre-hook commands will be run before any certs are +renewed, post-hook commands will be run after any certs are renewed, +and renew-hook commands will be run after each cert is renewed. If no +certs are due for renewal, no command is run. +* Added a -q/--quiet flag which silences all output except errors. +* Added an --allow-subset-of-domains flag which can be used with the renew +command to prevent renewal failures for a subset of the requested +domains from causing the client to exit. + +### Changed + +* Certbot now uses renewal configuration files. In /etc/letsencrypt/renewal +by default, these files can be used to control what parameters are +used when renewing a specific certificate. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.5.0+is%3Aissue + +## 0.4.2 - 2016-03-03 + +### Fixed + +* Resolved problems encountered when compiling letsencrypt +against the new OpenSSL release. +* Fixed problems encountered when using `letsencrypt renew` with configuration files +from the private beta. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.2 + +## 0.4.1 - 2016-02-29 + +### Fixed + +* Fixed Apache parsing errors encountered with some configurations. +* Fixed Werkzeug dependency problems encountered on some Red Hat systems. +* Fixed bootstrapping failures when using letsencrypt-auto with --no-self-upgrade. +* Fixed problems with parsing renewal config files from private beta. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is:issue+milestone:0.4.1 + +## 0.4.0 - 2016-02-10 + +### Added + +* Added the verb/subcommand `renew` which can be used to renew your existing +certificates as they approach expiration. Running `letsencrypt renew` +will examine all existing certificate lineages and determine if any are +less than 30 days from expiration. If so, the client will use the +settings provided when you previously obtained the certificate to renew +it. The subcommand finishes by printing a summary of which renewals were +successful, failed, or not yet due. +* Added a `--dry-run` flag to help with testing configuration +without affecting production rate limits. Currently supported by the +`renew` and `certonly` subcommands, providing `--dry-run` on the command +line will obtain certificates from the staging server without saving the +resulting certificates to disk. +* Added major improvements to letsencrypt-auto. This script +has been rewritten to include full support for Python 2.6, the ability +for letsencrypt-auto to update itself, and improvements to the +stability, security, and performance of the script. +* Added support for Apache 2.2 to the Apache plugin. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.4.0 + +## 0.3.0 - 2016-01-27 + +### Added + +* Added a non-interactive mode which can be enabled by including `-n` or +`--non-interactive` on the command line. This can be used to guarantee +the client will not prompt when run automatically using cron/systemd. +* Added preparation for the new letsencrypt-auto script. Over the past +couple months, we've been working on increasing the reliability and +security of letsencrypt-auto. A number of changes landed in this +release to prepare for the new version of this script. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.3.0 + +## 0.2.0 - 2016-01-14 + +### Added + +* Added Apache plugin support for non-Debian based systems. Support has been +added for modern Red Hat based systems such as Fedora 23, Red Hat 7, +and CentOS 7 running Apache 2.4. In theory, this plugin should be +able to be configured to run on any Unix-like OS running Apache 2.4. +* Relaxed PyOpenSSL version requirements. This adds support for systems +with PyOpenSSL versions 0.13 or 0.14. +* Improved error messages from the client. + +### Fixed + +* Resolved issues with the Apache plugin enabling an HTTP to HTTPS +redirect on some systems. + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=is%3Aissue+milestone%3A0.2.0 + +## 0.1.1 - 2015-12-15 + +### Added + +* Added a check that avoids attempting to issue for unqualified domain names like +"localhost". + +### Fixed + +* Fixed a confusing UI path that caused some users to repeatedly renew +their certs while experimenting with the client, in some cases hitting +issuance rate limits. +* Fixed numerous Apache configuration parser problems +* Fixed --webroot permission handling for non-root users + +More details about these changes can be found on our GitHub repo: +https://github.com/letsencrypt/letsencrypt/issues?q=milestone%3A0.1.1 diff --git a/certbot/LICENSE.txt b/certbot/LICENSE.txt new file mode 100644 index 000000000..b905dd120 --- /dev/null +++ b/certbot/LICENSE.txt @@ -0,0 +1,205 @@ +Certbot ACME Client +Copyright (c) Electronic Frontier Foundation and others +Licensed Apache Version 2.0 + +The nginx plugin incorporates code from nginxparser +Copyright (c) 2014 Fatih Erikli +Licensed MIT + + +Text of Apache License +====================== + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + +Text of MIT License +=================== +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/MANIFEST.in b/certbot/MANIFEST.in similarity index 70% rename from MANIFEST.in rename to certbot/MANIFEST.in index 7f529c7a7..ef91a3e7c 100644 --- a/MANIFEST.in +++ b/certbot/MANIFEST.in @@ -1,9 +1,10 @@ include README.rst include CHANGELOG.md -include CONTRIBUTING.md include LICENSE.txt -include linter_plugin.py recursive-include docs * recursive-include examples * recursive-include certbot/tests/testdata * +recursive-include tests *.py include certbot/ssl-dhparams.pem +global-exclude __pycache__ +global-exclude *.py[cod] diff --git a/certbot/README.rst b/certbot/README.rst new file mode 100644 index 000000000..2c934ce59 --- /dev/null +++ b/certbot/README.rst @@ -0,0 +1,131 @@ +.. This file contains a series of comments that are used to include sections of this README in other files. Do not modify these comments unless you know what you are doing. tag:intro-begin + +Certbot is part of EFF’s effort to encrypt the entire Internet. Secure communication over the Web relies on HTTPS, which requires the use of a digital certificate that lets browsers verify the identity of web servers (e.g., is that really google.com?). Web servers obtain their certificates from trusted third parties called certificate authorities (CAs). Certbot is an easy-to-use client that fetches a certificate from Let’s Encrypt—an open certificate authority launched by the EFF, Mozilla, and others—and deploys it to a web server. + +Anyone who has gone through the trouble of setting up a secure website knows what a hassle getting and maintaining a certificate is. Certbot and Let’s Encrypt can automate away the pain and let you turn on and manage HTTPS with simple commands. Using Certbot and Let's Encrypt is free, so there’s no need to arrange payment. + +How you use Certbot depends on the configuration of your web server. The best way to get started is to use our `interactive guide `_. It generates instructions based on your configuration settings. In most cases, you’ll need `root or administrator access `_ to your web server to run Certbot. + +Certbot is meant to be run directly on your web server, not on your personal computer. If you’re using a hosted service and don’t have direct access to your web server, you might not be able to use Certbot. Check with your hosting provider for documentation about uploading certificates or using certificates issued by Let’s Encrypt. + +Certbot is a fully-featured, extensible client for the Let's +Encrypt CA (or any other CA that speaks the `ACME +`_ +protocol) that can automate the tasks of obtaining certificates and +configuring webservers to use them. This client runs on Unix-based operating +systems. + +To see the changes made to Certbot between versions please refer to our +`changelog `_. + +Until May 2016, Certbot was named simply ``letsencrypt`` or ``letsencrypt-auto``, +depending on install method. Instructions on the Internet, and some pieces of the +software, may still refer to this older name. + +Contributing +------------ + +If you'd like to contribute to this project please read `Developer Guide +`_. + +This project is governed by `EFF's Public Projects Code of Conduct `_. + +.. _installation: + +How to run the client +--------------------- + +The easiest way to install and run Certbot is by visiting `certbot.eff.org`_, +where you can find the correct instructions for many web server and OS +combinations. For more information, see `Get Certbot +`_. + +.. _certbot.eff.org: https://certbot.eff.org/ + +Understanding the client in more depth +-------------------------------------- + +To understand what the client is doing in detail, it's important to +understand the way it uses plugins. Please see the `explanation of +plugins `_ in +the User Guide. + +Links +===== + +.. Do not modify this comment unless you know what you're doing. tag:links-begin + +Documentation: https://certbot.eff.org/docs + +Software project: https://github.com/certbot/certbot + +Notes for developers: https://certbot.eff.org/docs/contributing.html + +Main Website: https://certbot.eff.org + +Let's Encrypt Website: https://letsencrypt.org + +Community: https://community.letsencrypt.org + +ACME spec: http://ietf-wg-acme.github.io/acme/ + +ACME working area in github: https://github.com/ietf-wg-acme/acme + +|build-status| |coverage| |docs| |container| + +.. |build-status| image:: https://travis-ci.com/certbot/certbot.svg?branch=master + :target: https://travis-ci.com/certbot/certbot + :alt: Travis CI status + +.. |coverage| image:: https://codecov.io/gh/certbot/certbot/branch/master/graph/badge.svg + :target: https://codecov.io/gh/certbot/certbot + :alt: Coverage status + +.. |docs| image:: https://readthedocs.org/projects/letsencrypt/badge/ + :target: https://readthedocs.org/projects/letsencrypt/ + :alt: Documentation status + +.. |container| image:: https://quay.io/repository/letsencrypt/letsencrypt/status + :target: https://quay.io/repository/letsencrypt/letsencrypt + :alt: Docker Repository on Quay.io + +.. Do not modify this comment unless you know what you're doing. tag:links-end + +System Requirements +=================== + +See https://certbot.eff.org/docs/install.html#system-requirements. + +.. Do not modify this comment unless you know what you're doing. tag:intro-end + +.. Do not modify this comment unless you know what you're doing. tag:features-begin + +Current Features +===================== + +* Supports multiple web servers: + + - apache/2.x + - nginx/0.8.48+ + - webroot (adds files to webroot directories in order to prove control of + domains and obtain certs) + - standalone (runs its own simple webserver to prove you control a domain) + - other server software via `third party plugins `_ + +* The private key is generated locally on your system. +* Can talk to the Let's Encrypt CA or optionally to other ACME + compliant services. +* Can get domain-validated (DV) certificates. +* Can revoke certificates. +* Adjustable RSA key bit-length (2048 (default), 4096, ...). +* Can optionally install a http -> https redirect, so your site effectively + runs https only (Apache only) +* Fully automated. +* Configuration changes are logged and can be reverted. +* Supports an interactive text UI, or can be driven entirely from the + command line. +* Free and Open Source Software, made with Python. + +.. Do not modify this comment unless you know what you're doing. tag:features-end + +For extensive documentation on using and contributing to Certbot, go to https://certbot.eff.org/docs. If you would like to contribute to the project or run the latest code from git, you should read our `developer guide `_. diff --git a/certbot/__init__.py b/certbot/certbot/__init__.py similarity index 77% rename from certbot/__init__.py rename to certbot/certbot/__init__.py index 30b52be1a..caae1a041 100644 --- a/certbot/__init__.py +++ b/certbot/certbot/__init__.py @@ -1,4 +1,4 @@ """Certbot client.""" # version number like 1.2.3a0, must have at least 2 parts, like 1.2 -__version__ = '1.0.0.dev0' +__version__ = '1.2.0.dev0' diff --git a/certbot/_internal/__init__.py b/certbot/certbot/_internal/__init__.py similarity index 100% rename from certbot/_internal/__init__.py rename to certbot/certbot/_internal/__init__.py diff --git a/certbot/_internal/account.py b/certbot/certbot/_internal/account.py similarity index 98% rename from certbot/_internal/account.py rename to certbot/certbot/_internal/account.py index 12f6a3e8a..c4ea6ef35 100644 --- a/certbot/_internal/account.py +++ b/certbot/certbot/_internal/account.py @@ -6,26 +6,25 @@ import logging import shutil import socket +from cryptography.hazmat.primitives import serialization import josepy as jose import pyrfc3339 import pytz import six import zope.component -from cryptography.hazmat.primitives import serialization from acme import fields as acme_fields from acme import messages - -from certbot._internal import constants from certbot import errors from certbot import interfaces from certbot import util +from certbot._internal import constants from certbot.compat import os logger = logging.getLogger(__name__) -class Account(object): # pylint: disable=too-few-public-methods +class Account(object): """ACME protocol registration. :ivar .RegistrationResource regr: Registration Resource @@ -217,9 +216,8 @@ class AccountFileStorage(interfaces.AccountStorage): else: self._symlink_to_accounts_dir(prev_server_path, server_path) return prev_loaded_account - else: - raise errors.AccountNotFound( - "Account at %s does not exist" % account_dir_path) + raise errors.AccountNotFound( + "Account at %s does not exist" % account_dir_path) try: with open(self._regr_path(account_dir_path)) as regr_file: diff --git a/certbot/_internal/auth_handler.py b/certbot/certbot/_internal/auth_handler.py similarity index 98% rename from certbot/_internal/auth_handler.py rename to certbot/certbot/_internal/auth_handler.py index 5c037e8dc..e4ad91247 100644 --- a/certbot/_internal/auth_handler.py +++ b/certbot/certbot/_internal/auth_handler.py @@ -1,20 +1,20 @@ """ACME AuthHandler.""" +import datetime import logging import time -import datetime import zope.component from acme import challenges -from acme import messages from acme import errors as acme_errors -# pylint: disable=unused-import, no-name-in-module -from acme.magic_typing import Dict, List, Tuple -# pylint: enable=unused-import, no-name-in-module +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 Tuple # pylint: disable=unused-import, no-name-in-module from certbot import achallenges from certbot import errors -from certbot._internal import error_handler from certbot import interfaces +from certbot._internal import error_handler logger = logging.getLogger(__name__) @@ -285,9 +285,8 @@ def challb_to_achall(challb, account_key, domain): challb=challb, domain=domain, account_key=account_key) elif isinstance(chall, challenges.DNS): return achallenges.DNS(challb=challb, domain=domain) - else: - raise errors.Error( - "Received unsupported challenge of type: {0}".format(chall.typ)) + raise errors.Error( + "Received unsupported challenge of type: {0}".format(chall.typ)) def gen_challenge_path(challbs, preferences, combinations): diff --git a/certbot/_internal/cert_manager.py b/certbot/certbot/_internal/cert_manager.py similarity index 97% rename from certbot/_internal/cert_manager.py rename to certbot/certbot/_internal/cert_manager.py index ed72b12e5..1def76a3d 100644 --- a/certbot/_internal/cert_manager.py +++ b/certbot/certbot/_internal/cert_manager.py @@ -8,13 +8,12 @@ import pytz import zope.component from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - from certbot import crypto_util from certbot import errors from certbot import interfaces +from certbot import util from certbot._internal import ocsp from certbot._internal import storage -from certbot import util from certbot.compat import os from certbot.display import util as display_util @@ -33,7 +32,7 @@ def update_live_symlinks(config): .. note:: This assumes that the installation is using a Reverter object. :param config: Configuration. - :type config: :class:`certbot.configuration.NamespaceConfig` + :type config: :class:`certbot._internal.configuration.NamespaceConfig` """ for renewal_file in storage.renewal_conf_files(config): @@ -43,7 +42,7 @@ def rename_lineage(config): """Rename the specified lineage to the new name. :param config: Configuration. - :type config: :class:`certbot.configuration.NamespaceConfig` + :type config: :class:`certbot._internal.configuration.NamespaceConfig` """ disp = zope.component.getUtility(interfaces.IDisplay) @@ -70,7 +69,7 @@ def certificates(config): """Display information about certs configured with Certbot :param config: Configuration. - :type config: :class:`certbot.configuration.NamespaceConfig` + :type config: :class:`certbot._internal.configuration.NamespaceConfig` """ parsed_certs = [] parse_failures = [] @@ -136,7 +135,7 @@ def find_duplicative_certs(config, domains): undefined. :param config: Configuration. - :type config: :class:`certbot.configuration.NamespaceConfig` + :type config: :class:`certbot._internal.configuration.NamespaceConfig` :param domains: List of domain names :type domains: `list` of `str` @@ -243,8 +242,8 @@ def match_and_check_overlaps(cli_config, acceptable_matches, match_func, rv_func raise errors.Error("No match found for cert-path {0}!".format(cli_config.cert_path[0])) elif len(matched) > 1: raise errors.OverlappingMatchFound() - else: - return matched + return matched + def human_readable_cert_info(config, cert, skip_filter_checks=False): """ Returns a human readable description of info about a RenewableCert object""" diff --git a/certbot/cli.py b/certbot/certbot/_internal/cli.py similarity index 98% rename from certbot/cli.py rename to certbot/certbot/_internal/cli.py index 739eadd8a..9853d9b53 100644 --- a/certbot/cli.py +++ b/certbot/certbot/_internal/cli.py @@ -15,22 +15,21 @@ import zope.interface from zope.interface import interfaces as zope_interfaces from acme import challenges -# pylint: disable=unused-import, no-name-in-module -from acme.magic_typing import Any, Dict, Optional -# pylint: enable=unused-import, no-name-in-module - +from acme.magic_typing import Any # 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 Optional # pylint: disable=unused-import, no-name-in-module import certbot -import certbot.plugins.enhancements as enhancements -import certbot._internal.plugins.selection as plugin_selection -from certbot._internal import constants from certbot import crypto_util from certbot import errors -from certbot import hooks from certbot import interfaces from certbot import util +from certbot._internal import constants +from certbot._internal import hooks +from certbot._internal.plugins import disco as plugins_disco +import certbot._internal.plugins.selection as plugin_selection from certbot.compat import os from certbot.display import util as display_util -from certbot._internal.plugins import disco as plugins_disco +import certbot.plugins.enhancements as enhancements logger = logging.getLogger(__name__) @@ -93,8 +92,8 @@ obtain, install, and renew certificates: manage certificates: certificates Display information about certificates you have from Certbot - revoke Revoke a certificate (supply --cert-path or --cert-name) - delete Delete a certificate + revoke Revoke a certificate (supply --cert-name or --cert-path) + delete Delete a certificate (supply --cert-name) manage your account: register Create an ACME account @@ -288,10 +287,9 @@ def flag_default(name): def config_help(name, hidden=False): """Extract the help message for an `.IConfig` attribute.""" - # pylint: disable=no-member if hidden: return argparse.SUPPRESS - field = interfaces.IConfig.__getitem__(name) # type: zope.interface.interface.Attribute # pylint: disable=no-value-for-parameter + field = interfaces.IConfig.__getitem__(name) # type: zope.interface.interface.Attribute return field.__doc__ @@ -675,7 +673,7 @@ class HelpfulArgumentParser(object): parsed_args.actual_csr = (csr, typ) - csr_domains = set([d.lower() for d in domains]) + csr_domains = {d.lower() for d in domains} config_domains = set(parsed_args.domains) if csr_domains != config_domains: raise errors.ConfigurationError( @@ -848,11 +846,11 @@ class HelpfulArgumentParser(object): chosen_topic = "run" if chosen_topic == "all": # Addition of condition closes #6209 (removal of duplicate route53 option). - return dict([(t, True) if t != 'certbot-route53:auth' else (t, False) - for t in self.help_topics]) + return {t: t != 'certbot-route53:auth' for t in self.help_topics} elif not chosen_topic: - return dict([(t, False) for t in self.help_topics]) - return dict([(t, t == chosen_topic) for t in self.help_topics]) + return {t: False for t in self.help_topics} + return {t: t == chosen_topic for t in self.help_topics} + def _add_all_groups(helpful): helpful.add_group("automation", description="Flags for automating execution & other tweaks") @@ -870,7 +868,7 @@ def _add_all_groups(helpful): helpful.add_group(name, description=docs["opts"]) -def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: disable=too-many-statements +def prepare_and_parse_args(plugins, args, detect_defaults=False): """Returns parsed command line arguments. :param .PluginsRegistry plugins: available plugins @@ -881,7 +879,6 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis """ - # pylint: disable=too-many-statements helpful = HelpfulArgumentParser(args, plugins, detect_defaults) _add_all_groups(helpful) @@ -980,12 +977,6 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis "certificates. Updates to the Subscriber Agreement will still " "affect you, and will be effective 14 days after posting an " "update to the web site.") - # TODO: When `certbot register --update-registration` is fully deprecated, - # delete following helpful.add - helpful.add( - "register", "--update-registration", action="store_true", - default=flag_default("update_registration"), dest="update_registration", - help=argparse.SUPPRESS) helpful.add( ["register", "update_account", "unregister", "automation"], "-m", "--email", default=flag_default("email"), diff --git a/certbot/_internal/client.py b/certbot/certbot/_internal/client.py similarity index 98% rename from certbot/_internal/client.py rename to certbot/certbot/_internal/client.py index f694a0ae7..9ce741e38 100644 --- a/certbot/_internal/client.py +++ b/certbot/certbot/_internal/client.py @@ -3,36 +3,35 @@ import datetime import logging import platform -import OpenSSL -import josepy as jose -import zope.component from cryptography.hazmat.backends import default_backend -# https://github.com/python/typeshed/blob/master/third_party/ -# 2/cryptography/hazmat/primitives/asymmetric/rsa.pyi +# See https://github.com/pyca/cryptography/issues/4275 from cryptography.hazmat.primitives.asymmetric.rsa import generate_private_key # type: ignore +import josepy as jose +import OpenSSL +import zope.component from acme import client as acme_client from acme import crypto_util as acme_crypto_util from acme import errors as acme_errors from acme import messages -from acme.magic_typing import Optional, List # 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 Optional # pylint: disable=unused-import, no-name-in-module import certbot -from certbot._internal import account -from certbot._internal import auth_handler -from certbot import cli -from certbot._internal import constants from certbot import crypto_util -from certbot._internal import eff -from certbot._internal import error_handler from certbot import errors from certbot import interfaces -from certbot._internal import storage from certbot import util -from certbot.compat import os +from certbot._internal import account +from certbot._internal import auth_handler +from certbot._internal import cli +from certbot._internal import constants +from certbot._internal import eff +from certbot._internal import error_handler +from certbot._internal import storage from certbot._internal.display import enhancements -from certbot.display import ops as display_ops from certbot._internal.plugins import selection as plugin_selection +from certbot.compat import os +from certbot.display import ops as display_ops logger = logging.getLogger(__name__) @@ -225,11 +224,9 @@ def perform_registration(acme, config, tos_cb): "Please ensure it is a valid email and attempt " "registration again." % config.email) raise errors.Error(msg) - else: - config.email = display_ops.get_email(invalid=True) - return perform_registration(acme, config, tos_cb) - else: - raise + config.email = display_ops.get_email(invalid=True) + return perform_registration(acme, config, tos_cb) + raise class Client(object): @@ -361,7 +358,6 @@ class Client(object): return self.obtain_certificate(successful_domains) else: cert, chain = self.obtain_certificate_from_csr(csr, orderr) - return cert, chain, key, csr def _get_order_and_authorizations(self, csr_pem, best_effort): @@ -394,8 +390,6 @@ class Client(object): authzr = self.auth_handler.handle_authorizations(orderr, best_effort) return orderr.update(authorizations=authzr) - - # pylint: disable=no-member def obtain_and_enroll_certificate(self, domains, certname): """Obtain and enroll certificate. diff --git a/certbot/configuration.py b/certbot/certbot/_internal/configuration.py similarity index 98% rename from certbot/configuration.py rename to certbot/certbot/_internal/configuration.py index 48579eb1c..f3db207db 100644 --- a/certbot/configuration.py +++ b/certbot/certbot/_internal/configuration.py @@ -1,13 +1,13 @@ """Certbot user-supplied configuration.""" import copy +from six.moves.urllib import parse import zope.interface -from six.moves.urllib import parse # pylint: disable=relative-import -from certbot._internal import constants from certbot import errors from certbot import interfaces from certbot import util +from certbot._internal import constants from certbot.compat import misc from certbot.compat import os diff --git a/certbot/_internal/constants.py b/certbot/certbot/_internal/constants.py similarity index 99% rename from certbot/_internal/constants.py rename to certbot/certbot/_internal/constants.py index d8c3c2ae1..9a2220e0b 100644 --- a/certbot/_internal/constants.py +++ b/certbot/certbot/_internal/constants.py @@ -4,7 +4,6 @@ import logging import pkg_resources from acme import challenges - from certbot.compat import misc from certbot.compat import os @@ -32,7 +31,6 @@ CLI_DEFAULTS = dict( certname=None, dry_run=False, register_unsafely_without_email=False, - update_registration=False, email=None, eff_email=None, reinstall=False, diff --git a/certbot/_internal/display/__init__.py b/certbot/certbot/_internal/display/__init__.py similarity index 100% rename from certbot/_internal/display/__init__.py rename to certbot/certbot/_internal/display/__init__.py diff --git a/certbot/_internal/display/completer.py b/certbot/certbot/_internal/display/completer.py similarity index 99% rename from certbot/_internal/display/completer.py rename to certbot/certbot/_internal/display/completer.py index 3be06bec1..03719862b 100644 --- a/certbot/_internal/display/completer.py +++ b/certbot/certbot/_internal/display/completer.py @@ -1,5 +1,6 @@ """Provides Tab completion when prompting users for a path.""" import glob + # readline module is not available on all systems try: import readline diff --git a/certbot/_internal/display/dummy_readline.py b/certbot/certbot/_internal/display/dummy_readline.py similarity index 100% rename from certbot/_internal/display/dummy_readline.py rename to certbot/certbot/_internal/display/dummy_readline.py diff --git a/certbot/_internal/display/enhancements.py b/certbot/certbot/_internal/display/enhancements.py similarity index 98% rename from certbot/_internal/display/enhancements.py rename to certbot/certbot/_internal/display/enhancements.py index 5498b9547..ce6470708 100644 --- a/certbot/_internal/display/enhancements.py +++ b/certbot/certbot/_internal/display/enhancements.py @@ -7,7 +7,6 @@ from certbot import errors from certbot import interfaces from certbot.display import util as display_util - logger = logging.getLogger(__name__) # Define a helper function to avoid verbose code @@ -50,7 +49,7 @@ def redirect_by_default(): code, selection = util(interfaces.IDisplay).menu( "Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.", - choices, default=0, + choices, default=1, cli_flag="--redirect / --no-redirect", force_interactive=True) if code != display_util.OK: diff --git a/certbot/_internal/eff.py b/certbot/certbot/_internal/eff.py similarity index 99% rename from certbot/_internal/eff.py rename to certbot/certbot/_internal/eff.py index a0692009f..586697dbb 100644 --- a/certbot/_internal/eff.py +++ b/certbot/certbot/_internal/eff.py @@ -4,9 +4,8 @@ import logging import requests import zope.component -from certbot._internal import constants from certbot import interfaces - +from certbot._internal import constants logger = logging.getLogger(__name__) diff --git a/certbot/_internal/error_handler.py b/certbot/certbot/_internal/error_handler.py similarity index 93% rename from certbot/_internal/error_handler.py rename to certbot/certbot/_internal/error_handler.py index 1a570e48e..5ca3cc57e 100644 --- a/certbot/_internal/error_handler.py +++ b/certbot/certbot/_internal/error_handler.py @@ -4,10 +4,11 @@ import logging import signal import traceback -# pylint: disable=unused-import, no-name-in-module -from acme.magic_typing import Any, Callable, Dict, List, Union -# pylint: enable=unused-import, no-name-in-module - +from acme.magic_typing import Any # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import Callable # 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 Union # pylint: disable=unused-import, no-name-in-module from certbot import errors from certbot.compat import os @@ -92,7 +93,7 @@ class ErrorHandler(object): # SystemExit is ignored to properly handle forks that don't exec if exec_type is SystemExit: return retval - elif exec_type is None: + if exec_type is None: if not self.call_on_regular_exit: return retval elif exec_type is errors.SignalExit: diff --git a/certbot/hooks.py b/certbot/certbot/_internal/hooks.py similarity index 97% rename from certbot/hooks.py rename to certbot/certbot/_internal/hooks.py index 1bb3a2eab..25addd915 100644 --- a/certbot/hooks.py +++ b/certbot/certbot/_internal/hooks.py @@ -2,10 +2,11 @@ from __future__ import print_function import logging -from subprocess import Popen, PIPE - -from acme.magic_typing import Set, List # pylint: disable=unused-import, no-name-in-module +from subprocess import PIPE +from subprocess import Popen +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 certbot import errors from certbot import util from certbot.compat import filesystem diff --git a/certbot/_internal/lock.py b/certbot/certbot/_internal/lock.py similarity index 99% rename from certbot/_internal/lock.py rename to certbot/certbot/_internal/lock.py index eda2a72a1..7823eaac3 100644 --- a/certbot/_internal/lock.py +++ b/certbot/certbot/_internal/lock.py @@ -1,6 +1,12 @@ """Implements file locks compatible with Linux and Windows for locking files and directories.""" import errno import logging + +from acme.magic_typing import Optional # pylint: disable=unused-import, no-name-in-module +from certbot import errors +from certbot.compat import filesystem +from certbot.compat import os + try: import fcntl # pylint: disable=import-error except ImportError: @@ -9,11 +15,7 @@ except ImportError: else: POSIX_MODE = True -from acme.magic_typing import Optional # pylint: disable=unused-import, no-name-in-module -from certbot import errors -from certbot.compat import os -from certbot.compat import filesystem logger = logging.getLogger(__name__) diff --git a/certbot/_internal/log.py b/certbot/certbot/_internal/log.py similarity index 98% rename from certbot/_internal/log.py rename to certbot/certbot/_internal/log.py index 2109e0427..0a492ba55 100644 --- a/certbot/_internal/log.py +++ b/certbot/certbot/_internal/log.py @@ -23,10 +23,9 @@ import tempfile import traceback from acme import messages - -from certbot._internal import constants from certbot import errors from certbot import util +from certbot._internal import constants from certbot.compat import os # Logging format @@ -103,9 +102,9 @@ def post_arg_parse_setup(config): root_logger.addHandler(file_handler) root_logger.removeHandler(memory_handler) - temp_handler = memory_handler.target - memory_handler.setTarget(file_handler) - memory_handler.flush(force=True) + temp_handler = memory_handler.target # pylint: disable=no-member + memory_handler.setTarget(file_handler) # pylint: disable=no-member + memory_handler.flush(force=True) # pylint: disable=unexpected-keyword-arg memory_handler.close() temp_handler.close() diff --git a/certbot/_internal/main.py b/certbot/certbot/_internal/main.py similarity index 94% rename from certbot/_internal/main.py rename to certbot/certbot/_internal/main.py index dd5f7fe4a..509b5b981 100644 --- a/certbot/_internal/main.py +++ b/certbot/certbot/_internal/main.py @@ -12,32 +12,32 @@ import zope.component from acme import errors as acme_errors from acme.magic_typing import Union # pylint: disable=unused-import, no-name-in-module - import certbot +from certbot import crypto_util +from certbot import errors +from certbot import interfaces +from certbot import util from certbot._internal import account from certbot._internal import cert_manager -from certbot import cli +from certbot._internal import cli from certbot._internal import client -from certbot import configuration +from certbot._internal import configuration from certbot._internal import constants -from certbot import crypto_util from certbot._internal import eff -from certbot import errors -from certbot import hooks -from certbot import interfaces +from certbot._internal import hooks from certbot._internal import log from certbot._internal import renewal from certbot._internal import reporter from certbot._internal import storage from certbot._internal import updater -from certbot import util +from certbot._internal.plugins import disco as plugins_disco +from certbot._internal.plugins import selection as plug_sel from certbot.compat import filesystem from certbot.compat import misc from certbot.compat import os -from certbot.display import util as display_util, ops as display_ops -from certbot._internal.plugins import disco as plugins_disco +from certbot.display import ops as display_ops +from certbot.display import util as display_util from certbot.plugins import enhancements -from certbot._internal.plugins import selection as plug_sel USER_CANCELLED = ("User chose to cancel the operation and may " "reinvoke the client.") @@ -121,7 +121,7 @@ def _get_and_save_cert(le_client, config, domains=None, certname=None, lineage=N lineage = le_client.obtain_and_enroll_certificate(domains, certname) if lineage is False: raise errors.Error("Certificate could not be obtained") - elif lineage is not None: + if lineage is not None: hooks.deploy_hook(config, lineage.names(), lineage.live_dir) finally: hooks.post_hook(config) @@ -162,19 +162,18 @@ def _handle_subset_cert_request(config, domains, cert): cli_flag="--expand", force_interactive=True): return "renew", cert - else: - reporter_util = zope.component.getUtility(interfaces.IReporter) - reporter_util.add_message( - "To obtain a new certificate that contains these names without " - "replacing your existing certificate for {0}, you must use the " - "--duplicate option.{br}{br}" - "For example:{br}{br}{1} --duplicate {2}".format( - existing, - sys.argv[0], " ".join(sys.argv[1:]), - br=os.linesep - ), - reporter_util.HIGH_PRIORITY) - raise errors.Error(USER_CANCELLED) + reporter_util = zope.component.getUtility(interfaces.IReporter) + reporter_util.add_message( + "To obtain a new certificate that contains these names without " + "replacing your existing certificate for {0}, you must use the " + "--duplicate option.{br}{br}" + "For example:{br}{br}{1} --duplicate {2}".format( + existing, + sys.argv[0], " ".join(sys.argv[1:]), + br=os.linesep + ), + reporter_util.HIGH_PRIORITY) + raise errors.Error(USER_CANCELLED) def _handle_identical_cert_request(config, lineage): @@ -220,7 +219,7 @@ def _handle_identical_cert_request(config, lineage): # skipping the menu for this case. raise errors.Error( "Operation canceled. You may re-run the client.") - elif response[1] == 0: + if response[1] == 0: return "reinstall", lineage elif response[1] == 1: return "renew", lineage @@ -312,23 +311,20 @@ def _find_lineage_for_domains_and_certname(config, domains, certname): """ if not certname: return _find_lineage_for_domains(config, domains) - else: - lineage = cert_manager.lineage_for_certname(config, certname) - if lineage: - if domains: - if set(cert_manager.domains_for_certname(config, certname)) != set(domains): - _ask_user_to_confirm_new_names(config, domains, certname, - lineage.names()) # raises if no - return "renew", lineage - # unnecessarily specified domains or no domains specified - return _handle_identical_cert_request(config, lineage) - else: - if domains: - return "newcert", None - else: - raise errors.ConfigurationError("No certificate with name {0} found. " - "Use -d to specify domains, or run certbot certificates to see " - "possible certificate names.".format(certname)) + lineage = cert_manager.lineage_for_certname(config, certname) + if lineage: + if domains: + if set(cert_manager.domains_for_certname(config, certname)) != set(domains): + _ask_user_to_confirm_new_names(config, domains, certname, + lineage.names()) # raises if no + return "renew", lineage + # unnecessarily specified domains or no domains specified + return _handle_identical_cert_request(config, lineage) + elif domains: + return "newcert", None + raise errors.ConfigurationError("No certificate with name {0} found. " + "Use -d to specify domains, or run certbot certificates to see " + "possible certificate names.".format(certname)) def _get_added_removed(after, before): """Get lists of items removed from `before` @@ -532,7 +528,7 @@ def _determine_account(config): return acc, acme -def _delete_if_appropriate(config): # pylint: disable=too-many-locals,too-many-branches +def _delete_if_appropriate(config): """Does the user want to delete their now-revoked certs? If run in non-interactive mode, deleting happens automatically. @@ -668,14 +664,6 @@ def register(config, unused_plugins): :rtype: None or str """ - # TODO: When `certbot register --update-registration` is fully deprecated, - # delete the true case of if block - if config.update_registration: - msg = ("Usage 'certbot register --update-registration' is deprecated.\n" - "Please use 'certbot update_account [options]' instead.\n") - logger.warning(msg) - return update_account(config, unused_plugins) - # Portion of _determine_account logic to see whether accounts already # exist or not. account_storage = account.AccountFileStorage(config) @@ -1076,7 +1064,7 @@ def revoke(config, unused_plugins): return None -def run(config, plugins): # pylint: disable=too-many-branches,too-many-locals +def run(config, plugins): """Obtain a certificate and install. :param config: Configuration object @@ -1312,12 +1300,13 @@ def set_displayer(config): def main(cli_args=None): - """Command line argument parsing and main script execution. + """Run Certbot. - :returns: result of requested command + :param cli_args: command line to Certbot, defaults to ``sys.argv[1:]`` + :type cli_args: `list` of `str` - :raises errors.Error: OS errors triggered by wrong permissions - :raises errors.Error: error if plugin command is not supported + :returns: value for `sys.exit` about the exit status of Certbot + :rtype: `str` or `int` or `None` """ if not cli_args: @@ -1345,9 +1334,13 @@ def main(cli_args=None): make_or_verify_needed_dirs(config) except errors.Error: # Let plugins_cmd be run as un-privileged user. - if config.func != plugins_cmd: + if config.func != plugins_cmd: # pylint: disable=comparison-with-callable raise + if sys.version_info[:2] == (3, 4): + logger.warning("Python 3.4 support will be dropped in the next release " + "of Certbot - please upgrade your Python version to 3.5+.") + set_displayer(config) # Reporter @@ -1356,10 +1349,3 @@ def main(cli_args=None): util.atexit_register(report.print_messages) return config.func(config, plugins) - - -if __name__ == "__main__": - err_string = main() - if err_string: - logger.warning("Exiting with message %s", err_string) - sys.exit(err_string) # pragma: no cover diff --git a/certbot/_internal/notify.py b/certbot/certbot/_internal/notify.py similarity index 100% rename from certbot/_internal/notify.py rename to certbot/certbot/_internal/notify.py diff --git a/certbot/_internal/ocsp.py b/certbot/certbot/_internal/ocsp.py similarity index 95% rename from certbot/_internal/ocsp.py rename to certbot/certbot/_internal/ocsp.py index 2a63412a0..65a6d5c17 100644 --- a/certbot/_internal/ocsp.py +++ b/certbot/certbot/_internal/ocsp.py @@ -1,29 +1,37 @@ """Tools for checking certificate revocation.""" +from datetime import datetime +from datetime import timedelta import logging import re -from datetime import datetime, timedelta -from subprocess import Popen, PIPE +from subprocess import PIPE +from subprocess import Popen + +from cryptography import x509 +from cryptography.exceptions import InvalidSignature +from cryptography.exceptions import UnsupportedAlgorithm +from cryptography.hazmat.backends import default_backend +# See https://github.com/pyca/cryptography/issues/4275 +from cryptography.hazmat.primitives import hashes # type: ignore +from cryptography.hazmat.primitives import serialization +import pytz +import requests + +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 certbot import crypto_util +from certbot import errors +from certbot import util +from certbot._internal.storage import RenewableCert # pylint: disable=unused-import try: # Only cryptography>=2.5 has ocsp module # and signature_hash_algorithm attribute in OCSPResponse class - from cryptography.x509 import ocsp # pylint: disable=import-error + from cryptography.x509 import ocsp # pylint: disable=import-error, ungrouped-imports getattr(ocsp.OCSPResponse, 'signature_hash_algorithm') except (ImportError, AttributeError): # pragma: no cover ocsp = None # type: ignore -from cryptography import x509 -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import serialization -from cryptography.hazmat.primitives import hashes # type: ignore -from cryptography.exceptions import UnsupportedAlgorithm, InvalidSignature -import pytz -import requests -from acme.magic_typing import Optional, Tuple # pylint: disable=unused-import, no-name-in-module -from certbot import crypto_util -from certbot import errors -from certbot._internal.storage import RenewableCert # pylint: disable=unused-import -from certbot import util + logger = logging.getLogger(__name__) @@ -288,5 +296,5 @@ def _translate_ocsp_query(cert_path, ocsp_output, ocsp_errors): return True else: logger.warning("Unable to properly parse OCSP output: %s\nstderr:%s", - ocsp_output, ocsp_errors) + ocsp_output, ocsp_errors) return False diff --git a/certbot/_internal/plugins/__init__.py b/certbot/certbot/_internal/plugins/__init__.py similarity index 100% rename from certbot/_internal/plugins/__init__.py rename to certbot/certbot/_internal/plugins/__init__.py diff --git a/certbot/_internal/plugins/disco.py b/certbot/certbot/_internal/plugins/disco.py similarity index 99% rename from certbot/_internal/plugins/disco.py rename to certbot/certbot/_internal/plugins/disco.py index 0bee88ae1..360597474 100644 --- a/certbot/_internal/plugins/disco.py +++ b/certbot/certbot/_internal/plugins/disco.py @@ -5,15 +5,13 @@ import logging import pkg_resources import six - import zope.interface import zope.interface.verify from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module -from certbot._internal import constants from certbot import errors from certbot import interfaces - +from certbot._internal import constants logger = logging.getLogger(__name__) diff --git a/certbot/_internal/plugins/manual.py b/certbot/certbot/_internal/plugins/manual.py similarity index 99% rename from certbot/_internal/plugins/manual.py rename to certbot/certbot/_internal/plugins/manual.py index 4bb11de3f..be6abaad4 100644 --- a/certbot/_internal/plugins/manual.py +++ b/certbot/certbot/_internal/plugins/manual.py @@ -4,12 +4,11 @@ import zope.interface from acme import challenges from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module - from certbot import achallenges # pylint: disable=unused-import from certbot import errors -from certbot import hooks from certbot import interfaces from certbot import reverter +from certbot._internal import hooks from certbot.compat import os from certbot.plugins import common diff --git a/certbot/_internal/plugins/null.py b/certbot/certbot/_internal/plugins/null.py similarity index 99% rename from certbot/_internal/plugins/null.py rename to certbot/certbot/_internal/plugins/null.py index 6deb358f1..bf4615497 100644 --- a/certbot/_internal/plugins/null.py +++ b/certbot/certbot/_internal/plugins/null.py @@ -7,7 +7,6 @@ import zope.interface from certbot import interfaces from certbot.plugins import common - logger = logging.getLogger(__name__) diff --git a/certbot/_internal/plugins/selection.py b/certbot/certbot/_internal/plugins/selection.py similarity index 97% rename from certbot/_internal/plugins/selection.py rename to certbot/certbot/_internal/plugins/selection.py index ae3d8448b..6d87e4b07 100644 --- a/certbot/_internal/plugins/selection.py +++ b/certbot/certbot/_internal/plugins/selection.py @@ -64,9 +64,8 @@ def get_unprepared_installer(config, plugins): inst = list(installers.values())[0] logger.debug("Selecting plugin: %s", inst) return inst.init(config) - else: - raise errors.PluginSelectionError( - "Could not select or initialize the requested installer %s." % req_inst) + raise errors.PluginSelectionError( + "Could not select or initialize the requested installer %s." % req_inst) def pick_plugin(config, default, plugins, question, ifaces): """Pick plugin. @@ -175,7 +174,6 @@ def record_chosen_plugins(config, plugins, auth, inst): def choose_configurator_plugins(config, plugins, verb): - # pylint: disable=too-many-branches """ Figure out which configurator we're going to use, modifies config.authenticator and config.installer strings to reflect that choice if @@ -197,7 +195,7 @@ def choose_configurator_plugins(config, plugins, verb): # Which plugins do we need? if verb == "run": need_inst = need_auth = True - from certbot.cli import cli_command + from certbot._internal.cli import cli_command if req_auth in noninstaller_plugins and not req_inst: msg = ('With the {0} plugin, you probably want to use the "certonly" command, eg:{1}' '{1} {2} certonly --{0}{1}{1}' @@ -210,7 +208,7 @@ def choose_configurator_plugins(config, plugins, verb): need_inst = need_auth = False if verb == "certonly": need_auth = True - if verb == "install" or verb == "enhance": + elif verb in ("install", "enhance"): need_inst = True if config.authenticator: logger.warning("Specifying an authenticator doesn't make sense when " @@ -254,7 +252,7 @@ def set_configurator(previously, now): return now -def cli_plugin_requests(config): # pylint: disable=too-many-branches +def cli_plugin_requests(config): """ Figure out which plugins the user requested with CLI and config options @@ -328,7 +326,7 @@ def diagnose_configurator_problem(cfg_type, requested, plugins): "your existing configuration.\nThe error was: {1!r}" .format(requested, plugins[requested].problem)) elif cfg_type == "installer": - from certbot.cli import cli_command + from certbot._internal.cli import cli_command msg = ('Certbot doesn\'t know how to automatically configure the web ' 'server on this system. However, it can still get a certificate for ' 'you. Please run "{0} certonly" to do so. You\'ll need to ' diff --git a/certbot/_internal/plugins/standalone.py b/certbot/certbot/_internal/plugins/standalone.py similarity index 93% rename from certbot/_internal/plugins/standalone.py rename to certbot/certbot/_internal/plugins/standalone.py index 9723116c1..80421299e 100644 --- a/certbot/_internal/plugins/standalone.py +++ b/certbot/certbot/_internal/plugins/standalone.py @@ -11,13 +11,14 @@ import zope.interface from acme import challenges from acme import standalone as acme_standalone -# pylint: disable=unused-import, no-name-in-module -from acme.magic_typing import DefaultDict, Dict, Set, Tuple, List, Type, TYPE_CHECKING - +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 Set # 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 TYPE_CHECKING # pylint: disable=unused-import, no-name-in-module from certbot import achallenges # pylint: disable=unused-import from certbot import errors from certbot import interfaces - from certbot.plugins import common logger = logging.getLogger(__name__) @@ -75,7 +76,6 @@ class ServerManager(object): servers.serve_forever() # if port == 0, then random free port on OS is taken - # pylint: disable=no-member # both servers, if they exist, have the same port real_port = servers.getsocknames()[0][1] self._instances[real_port] = servers @@ -195,7 +195,7 @@ def _handle_perform_error(error): "the appropriate permissions (for example, you " "aren't running this program as " "root).".format(error.port)) - elif error.socket_error.errno == socket_errors.EADDRINUSE: + if error.socket_error.errno == socket_errors.EADDRINUSE: display = zope.component.getUtility(interfaces.IDisplay) msg = ( "Could not bind TCP port {0} because it is already in " diff --git a/certbot/_internal/plugins/webroot.py b/certbot/certbot/_internal/plugins/webroot.py similarity index 94% rename from certbot/_internal/plugins/webroot.py rename to certbot/certbot/_internal/plugins/webroot.py index 33e6530a1..c7737e0d1 100644 --- a/certbot/_internal/plugins/webroot.py +++ b/certbot/certbot/_internal/plugins/webroot.py @@ -10,16 +10,16 @@ import zope.component import zope.interface from acme import challenges # pylint: disable=unused-import -# pylint: disable=unused-import, no-name-in-module -from acme.magic_typing import Dict, Set, DefaultDict, List -# pylint: enable=unused-import, no-name-in-module - +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 certbot import achallenges # pylint: disable=unused-import -from certbot import cli from certbot import errors from certbot import interfaces -from certbot.compat import os +from certbot._internal import cli from certbot.compat import filesystem +from certbot.compat import os from certbot.display import ops from certbot.display import util as display_util from certbot.plugins import common @@ -135,8 +135,7 @@ to serve all files under specified web root ({0}).""" raise errors.PluginError( "Every requested domain must have a " "webroot when using the webroot plugin.") - else: # code == display_util.OK - return None if index == 0 else known_webroots[index - 1] + return None if index == 0 else known_webroots[index - 1] # code == display_util.OK def _prompt_for_new_webroot(self, domain, allowraise=False): code, webroot = ops.validated_directory( @@ -146,12 +145,10 @@ to serve all files under specified web root ({0}).""" if code == display_util.CANCEL: if not allowraise: return None - else: - raise errors.PluginError( - "Every requested domain must have a " - "webroot when using the webroot plugin.") - else: # code == display_util.OK - return _validate_webroot(webroot) + raise errors.PluginError( + "Every requested domain must have a " + "webroot when using the webroot plugin.") + return _validate_webroot(webroot) # code == display_util.OK def _create_challenge_dirs(self): path_map = self.conf("map") diff --git a/certbot/_internal/renewal.py b/certbot/certbot/_internal/renewal.py similarity index 98% rename from certbot/_internal/renewal.py rename to certbot/certbot/_internal/renewal.py index 31833c806..0426b2e2d 100644 --- a/certbot/_internal/renewal.py +++ b/certbot/certbot/_internal/renewal.py @@ -14,17 +14,16 @@ import six import zope.component from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - -from certbot import cli from certbot import crypto_util from certbot import errors -from certbot import hooks from certbot import interfaces +from certbot import util +from certbot._internal import cli +from certbot._internal import hooks from certbot._internal import storage from certbot._internal import updater -from certbot import util -from certbot.compat import os from certbot._internal.plugins import disco as plugins_disco +from certbot.compat import os logger = logging.getLogger(__name__) @@ -372,7 +371,7 @@ def _renew_describe_results(config, renew_successes, renew_failures, disp.notification("\n".join(out), wrap=False) -def handle_renewal_request(config): # pylint: disable=too-many-locals,too-many-branches,too-many-statements +def handle_renewal_request(config): """Examine each lineage; renew if due and report results""" # This is trivially False if config.domains is empty @@ -472,5 +471,4 @@ def handle_renewal_request(config): # pylint: disable=too-many-locals,too-many- if renew_failures or parse_failures: raise errors.Error("{0} renew failure(s), {1} parse failure(s)".format( len(renew_failures), len(parse_failures))) - else: - logger.debug("no renewal failures") + logger.debug("no renewal failures") diff --git a/certbot/_internal/reporter.py b/certbot/certbot/_internal/reporter.py similarity index 99% rename from certbot/_internal/reporter.py rename to certbot/certbot/_internal/reporter.py index e0063d8e5..947f343d4 100644 --- a/certbot/_internal/reporter.py +++ b/certbot/certbot/_internal/reporter.py @@ -12,7 +12,6 @@ import zope.interface from certbot import interfaces from certbot import util - logger = logging.getLogger(__name__) diff --git a/certbot/_internal/storage.py b/certbot/certbot/_internal/storage.py similarity index 97% rename from certbot/_internal/storage.py rename to certbot/certbot/_internal/storage.py index b7b878dab..964515eee 100644 --- a/certbot/_internal/storage.py +++ b/certbot/certbot/_internal/storage.py @@ -12,16 +12,17 @@ import pytz import six import certbot -from certbot import cli -from certbot._internal import constants from certbot import crypto_util -from certbot._internal import error_handler from certbot import errors +from certbot import interfaces from certbot import util -from certbot.compat import os -from certbot.compat import filesystem -from certbot.plugins import common as plugins_common +from certbot._internal import cli +from certbot._internal import constants +from certbot._internal import error_handler from certbot._internal.plugins import disco as plugins_disco +from certbot.compat import filesystem +from certbot.compat import os +from certbot.plugins import common as plugins_common logger = logging.getLogger(__name__) @@ -376,8 +377,7 @@ def delete_files(config, certname): logger.debug("Unable to remove %s", archive_path) -class RenewableCert(object): - # pylint: disable=too-many-instance-attributes,too-many-public-methods +class RenewableCert(interfaces.RenewableCert): """Renewable certificate. Represents a lineage of certificates that is under the management of @@ -424,7 +424,7 @@ class RenewableCert(object): """ self.cli_config = cli_config - self.lineagename = lineagename_for_filename(config_filename) + self._lineagename = lineagename_for_filename(config_filename) # self.configuration should be used to read parameters that # may have been chosen based on default values from the @@ -484,6 +484,15 @@ class RenewableCert(object): """Duck type for self.fullchain""" return self.fullchain + @property + def lineagename(self): + """Name given to the certificate lineage. + + :rtype: str + + """ + return self._lineagename + @property def target_expiry(self): """The current target certificate's expiration datetime @@ -859,21 +868,15 @@ class RenewableCert(object): for _, link in previous_links: os.unlink(link) - def names(self, version=None): + def names(self): """What are the subject names of this certificate? - (If no version is specified, use the current version.) - - :param int version: the desired version number :returns: the subject names :rtype: `list` of `str` :raises .CertStorageError: if could not find cert file. """ - if version is None: - target = self.current_target("cert") - else: - target = self.version("cert", version) + target = self.current_target("cert") if target is None: raise errors.CertStorageError("could not find cert file") with open(target) as f: @@ -952,7 +955,6 @@ class RenewableCert(object): @classmethod def new_lineage(cls, lineagename, cert, privkey, chain, cli_config): - # pylint: disable=too-many-locals """Create a new certificate lineage. Attempts to create a certificate lineage -- enrolled for @@ -1012,10 +1014,8 @@ class RenewableCert(object): "directory %s created.", archive, live_dir) # Put the data into the appropriate files on disk - target = dict([(kind, os.path.join(live_dir, kind + ".pem")) - for kind in ALL_FOUR]) - archive_target = dict([(kind, os.path.join(archive, kind + "1.pem")) - for kind in ALL_FOUR]) + target = {kind: os.path.join(live_dir, kind + ".pem") for kind in ALL_FOUR} + archive_target = {kind: os.path.join(archive, kind + "1.pem") for kind in ALL_FOUR} for kind in ALL_FOUR: os.symlink(_relpath_from_file(archive_target[kind], target[kind]), target[kind]) with open(target["cert"], "wb") as f: @@ -1080,10 +1080,8 @@ class RenewableCert(object): self.cli_config = cli_config target_version = self.next_free_version() - target = dict( - [(kind, - os.path.join(self.archive_dir, "{0}{1}.pem".format(kind, target_version))) - for kind in ALL_FOUR]) + target = {kind: os.path.join(self.archive_dir, "{0}{1}.pem".format(kind, target_version)) + for kind in ALL_FOUR} old_privkey = os.path.join( self.archive_dir, "privkey{0}.pem".format(prior_version)) diff --git a/certbot/_internal/updater.py b/certbot/certbot/_internal/updater.py similarity index 99% rename from certbot/_internal/updater.py rename to certbot/certbot/_internal/updater.py index 50db0e21c..961436ca5 100644 --- a/certbot/_internal/updater.py +++ b/certbot/certbot/_internal/updater.py @@ -3,7 +3,6 @@ import logging from certbot import errors from certbot import interfaces - from certbot._internal.plugins import selection as plug_sel import certbot.plugins.enhancements as enhancements diff --git a/certbot/achallenges.py b/certbot/certbot/achallenges.py similarity index 97% rename from certbot/achallenges.py rename to certbot/certbot/achallenges.py index 6535a6b63..70588683d 100644 --- a/certbot/achallenges.py +++ b/certbot/certbot/achallenges.py @@ -23,11 +23,9 @@ import josepy as jose from acme import challenges - logger = logging.getLogger(__name__) -# pylint: disable=too-few-public-methods class AnnotatedChallenge(jose.ImmutableMap): """Client annotated challenge. diff --git a/certbot/compat/__init__.py b/certbot/certbot/compat/__init__.py similarity index 100% rename from certbot/compat/__init__.py rename to certbot/certbot/compat/__init__.py diff --git a/certbot/compat/_path.py b/certbot/certbot/compat/_path.py similarity index 94% rename from certbot/compat/_path.py rename to certbot/certbot/compat/_path.py index fe2d2d1d2..5c5fe460e 100644 --- a/certbot/compat/_path.py +++ b/certbot/certbot/compat/_path.py @@ -1,4 +1,8 @@ -"""This compat module wraps os.path to forbid some functions.""" +""" +This compat module wraps os.path to forbid some functions. + +isort:skip_file +""" # pylint: disable=function-redefined from __future__ import absolute_import diff --git a/certbot/compat/filesystem.py b/certbot/certbot/compat/filesystem.py similarity index 94% rename from certbot/compat/filesystem.py rename to certbot/certbot/compat/filesystem.py index 69a3a63c5..ba4a155e8 100644 --- a/certbot/compat/filesystem.py +++ b/certbot/certbot/compat/filesystem.py @@ -5,6 +5,10 @@ import errno import os # pylint: disable=os-module-forbidden import stat +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 Union # pylint: disable=unused-import, no-name-in-module + try: # pylint: disable=import-error import ntsecuritycon @@ -20,8 +24,6 @@ except ImportError: else: POSIX_MODE = False -from acme.magic_typing import List, Union, Tuple # pylint: disable=unused-import, no-name-in-module - def chmod(file_path, mode): # type: (str, int) -> None @@ -69,6 +71,9 @@ def copy_ownership_and_apply_mode(src, dst, mode, copy_user, copy_group): stats = os.stat(src) user_id = stats.st_uid if copy_user else -1 group_id = stats.st_gid if copy_group else -1 + # On Windows, os.chown does not exist. This is checked through POSIX_MODE value, + # but MyPy/PyLint does not know it and raises an error here on Windows. + # We disable specifically the check to fix the issue. os.chown(dst, user_id, group_id) elif copy_user: # There is no group handling in Windows @@ -103,7 +108,10 @@ def check_owner(file_path): :return: True if given file is owned by current user, False otherwise. """ if POSIX_MODE: - return os.stat(file_path).st_uid == os.getuid() + # On Windows, os.getuid does not exist. This is checked through POSIX_MODE value, + # but MyPy/PyLint does not know it and raises an error here on Windows. + # We disable specifically the check to fix the issue. + return os.stat(file_path).st_uid == os.getuid() # type: ignore # Get owner sid of the file security = win32security.GetFileSecurity(file_path, win32security.OWNER_SECURITY_INFORMATION) @@ -588,7 +596,11 @@ def _get_current_user(): """ Return the pySID corresponding to the current user. """ - account_name = win32api.GetUserNameEx(win32api.NameSamCompatible) + # We craft the account_name ourselves instead of calling for instance win32api.GetUserNameEx, + # because this function returns nonsense values when Certbot is run under NT AUTHORITY\SYSTEM. + # To run Certbot under NT AUTHORITY\SYSTEM, you can open a shell using the instructions here: + # https://blogs.technet.microsoft.com/ben_parker/2010/10/27/how-do-i-run-powershell-execommand-prompt-as-the-localsystem-account-on-windows-7/ + account_name = r"{0}\{1}".format(win32api.GetDomainName(), win32api.GetUserName()) # LookupAccountName() expects the system name as first parameter. By passing None to it, # we instruct Windows to first search the matching account in the machine local accounts, # then into the primary domain accounts, if the machine has joined a domain, then finally diff --git a/certbot/compat/misc.py b/certbot/certbot/compat/misc.py similarity index 99% rename from certbot/compat/misc.py rename to certbot/certbot/compat/misc.py index a8fbf2c96..ffe611edb 100644 --- a/certbot/compat/misc.py +++ b/certbot/certbot/compat/misc.py @@ -7,14 +7,15 @@ from __future__ import absolute_import import select import sys +from certbot import errors +from certbot.compat import os + try: from win32com.shell import shell as shellwin32 # pylint: disable=import-error POSIX_MODE = False except ImportError: # pragma: no cover POSIX_MODE = True -from certbot import errors -from certbot.compat import os # For Linux: define OS specific standard binary directories diff --git a/certbot/compat/os.py b/certbot/certbot/compat/os.py similarity index 99% rename from certbot/compat/os.py rename to certbot/certbot/compat/os.py index e5438f365..0231dd51a 100644 --- a/certbot/compat/os.py +++ b/certbot/certbot/compat/os.py @@ -2,6 +2,8 @@ This compat modules is a wrapper of the core os module that forbids usage of specific operations (e.g. chown, chmod, getuid) that would be harmful to the Windows file security model of Certbot. This module is intended to replace standard os module throughout certbot projects (except acme). + +isort:skip_file """ # pylint: disable=function-redefined from __future__ import absolute_import diff --git a/certbot/crypto_util.py b/certbot/certbot/crypto_util.py similarity index 94% rename from certbot/crypto_util.py rename to certbot/certbot/crypto_util.py index 12291af38..9aae75991 100644 --- a/certbot/crypto_util.py +++ b/certbot/certbot/crypto_util.py @@ -8,12 +8,7 @@ import hashlib import logging import warnings -import pyrfc3339 -import six -import zope.component -from OpenSSL import SSL # type: ignore -from OpenSSL import crypto -# https://github.com/python/typeshed/tree/master/third_party/2/cryptography +# See https://github.com/pyca/cryptography/issues/4275 from cryptography import x509 # type: ignore from cryptography.exceptions import InvalidSignature from cryptography.hazmat.backends import default_backend @@ -21,10 +16,14 @@ from cryptography.hazmat.primitives.asymmetric.ec import ECDSA from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15 from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey +from OpenSSL import crypto +from OpenSSL import SSL # type: ignore +import pyrfc3339 +import six +import zope.component from acme import crypto_util as acme_crypto_util from acme.magic_typing import IO # pylint: disable=unused-import, no-name-in-module - from certbot import errors from certbot import interfaces from certbot import util @@ -213,26 +212,28 @@ def verify_renewable_cert(renewable_cert): 2. That fullchain matches cert and chain when concatenated. 3. Check that the private key matches the certificate. - :param `.storage.RenewableCert` renewable_cert: cert to verify + :param renewable_cert: cert to verify + :type renewable_cert: certbot.interfaces.RenewableCert :raises errors.Error: If verification fails. """ verify_renewable_cert_sig(renewable_cert) verify_fullchain(renewable_cert) - verify_cert_matches_priv_key(renewable_cert.cert, renewable_cert.privkey) + verify_cert_matches_priv_key(renewable_cert.cert_path, renewable_cert.key_path) def verify_renewable_cert_sig(renewable_cert): - """Verifies the signature of a `.storage.RenewableCert` object. + """Verifies the signature of a RenewableCert object. - :param `.storage.RenewableCert` renewable_cert: cert to verify + :param renewable_cert: cert to verify + :type renewable_cert: certbot.interfaces.RenewableCert :raises errors.Error: If signature verification fails. """ try: - with open(renewable_cert.chain, 'rb') as chain_file: # type: IO[bytes] + with open(renewable_cert.chain_path, 'rb') as chain_file: # type: IO[bytes] chain = x509.load_pem_x509_certificate(chain_file.read(), default_backend()) - with open(renewable_cert.cert, 'rb') as cert_file: # type: IO[bytes] + with open(renewable_cert.cert_path, 'rb') as cert_file: # type: IO[bytes] cert = x509.load_pem_x509_certificate(cert_file.read(), default_backend()) pk = chain.public_key() with warnings.catch_warnings(): @@ -240,7 +241,7 @@ def verify_renewable_cert_sig(renewable_cert): cert.signature_hash_algorithm) except (IOError, ValueError, InvalidSignature) as e: error_str = "verifying the signature of the cert located at {0} has failed. \ - Details: {1}".format(renewable_cert.cert, e) + Details: {1}".format(renewable_cert.cert_path, e) logger.exception(error_str) raise errors.Error(error_str) @@ -301,16 +302,17 @@ def verify_cert_matches_priv_key(cert_path, key_path): def verify_fullchain(renewable_cert): """ Verifies that fullchain is indeed cert concatenated with chain. - :param `.storage.RenewableCert` renewable_cert: cert to verify + :param renewable_cert: cert to verify + :type renewable_cert: certbot.interfaces.RenewableCert :raises errors.Error: If cert and chain do not combine to fullchain. """ try: - with open(renewable_cert.chain) as chain_file: # type: IO[str] + with open(renewable_cert.chain_path) as chain_file: # type: IO[str] chain = chain_file.read() - with open(renewable_cert.cert) as cert_file: # type: IO[str] + with open(renewable_cert.cert_path) as cert_file: # type: IO[str] cert = cert_file.read() - with open(renewable_cert.fullchain) as fullchain_file: # type: IO[str] + with open(renewable_cert.fullchain_path) as fullchain_file: # type: IO[str] fullchain = fullchain_file.read() if (cert + chain) != fullchain: error_str = "fullchain does not match cert + chain for {0}!" diff --git a/certbot/display/__init__.py b/certbot/certbot/display/__init__.py similarity index 100% rename from certbot/display/__init__.py rename to certbot/certbot/display/__init__.py diff --git a/certbot/display/ops.py b/certbot/certbot/display/ops.py similarity index 98% rename from certbot/display/ops.py rename to certbot/certbot/display/ops.py index 1a36744a5..92b09d6a1 100644 --- a/certbot/display/ops.py +++ b/certbot/certbot/display/ops.py @@ -60,11 +60,10 @@ def get_email(invalid=False, optional=True): raise errors.Error( "An e-mail address or " "--register-unsafely-without-email must be provided.") - else: - raise errors.Error("An e-mail address must be provided.") - elif util.safe_email(email): + raise errors.Error("An e-mail address must be provided.") + if util.safe_email(email): return email - elif suggest_unsafe: + if suggest_unsafe: msg += unsafe_suggestion suggest_unsafe = False # add this message at most once @@ -292,7 +291,7 @@ def _gen_ssl_lab_urls(domains): def _gen_https_names(domains): """Returns a string of the https domains. - Domains are formatted nicely with https:// prepended to each. + Domains are formatted nicely with ``https://`` prepended to each. :param list domains: Each domain is a 'str' diff --git a/certbot/display/util.py b/certbot/certbot/display/util.py similarity index 97% rename from certbot/display/util.py rename to certbot/certbot/display/util.py index 6cf9f9c05..ba2dd4ecf 100644 --- a/certbot/display/util.py +++ b/certbot/certbot/display/util.py @@ -5,12 +5,12 @@ import textwrap import zope.interface -from certbot._internal import constants from certbot import errors from certbot import interfaces +from certbot._internal import constants +from certbot._internal.display import completer from certbot.compat import misc from certbot.compat import os -from certbot._internal.display import completer logger = logging.getLogger(__name__) @@ -89,7 +89,6 @@ def input_with_timeout(prompt=None, timeout=36000.0): @zope.interface.implementer(interfaces.IDisplay) class FileDisplay(object): """File-based display.""" - # pylint: disable=too-many-arguments # see https://github.com/certbot/certbot/issues/3915 def __init__(self, outfile, force_interactive): @@ -178,7 +177,7 @@ class FileDisplay(object): message = _wrap_lines("%s (Enter 'c' to cancel):" % message) + " " ans = input_with_timeout(message) - if ans == "c" or ans == "C": + if ans in ("c", "C"): return CANCEL, "-1" return OK, ans @@ -259,10 +258,9 @@ class FileDisplay(object): selected_tags = self._scrub_checklist_input(indices, tags) if selected_tags: return code, selected_tags - else: - self.outfile.write( - "** Error - Invalid selection **%s" % os.linesep) - self.outfile.flush() + self.outfile.write( + "** Error - Invalid selection **%s" % os.linesep) + self.outfile.flush() else: return code, [] @@ -283,18 +281,17 @@ class FileDisplay(object): # assert_valid_call(prompt, default, cli_flag, force_interactive) if self._can_interact(force_interactive): return False - elif default is None: + if default is None: msg = "Unable to get an answer for the question:\n{0}".format(prompt) if cli_flag: msg += ( "\nYou can provide an answer on the " "command line with the {0} flag.".format(cli_flag)) raise errors.Error(msg) - else: - logger.debug( - "Falling back to default %s for the prompt:\n%s", - default, prompt) - return True + logger.debug( + "Falling back to default %s for the prompt:\n%s", + default, prompt) + return True def _can_interact(self, force_interactive): """Can we safely interact with the user? @@ -309,7 +306,7 @@ class FileDisplay(object): if (self.force_interactive or force_interactive or sys.stdin.isatty() and self.outfile.isatty()): return True - elif not self.skipped_interaction: + if not self.skipped_interaction: logger.warning( "Skipped user interaction because Certbot doesn't appear to " "be running in a terminal. You should probably include " @@ -482,7 +479,7 @@ class NoninteractiveDisplay(object): def menu(self, message, choices, ok_label=None, cancel_label=None, help_label=None, default=None, cli_flag=None, **unused_kwargs): - # pylint: disable=unused-argument,too-many-arguments + # pylint: disable=unused-argument """Avoid displaying a menu. :param str message: title of menu diff --git a/certbot/errors.py b/certbot/certbot/errors.py similarity index 100% rename from certbot/errors.py rename to certbot/certbot/errors.py diff --git a/certbot/interfaces.py b/certbot/certbot/interfaces.py similarity index 94% rename from certbot/interfaces.py rename to certbot/certbot/interfaces.py index 8cdd247d8..e96712d23 100644 --- a/certbot/interfaces.py +++ b/certbot/certbot/interfaces.py @@ -1,10 +1,10 @@ """Certbot client interfaces.""" import abc + import six import zope.interface # pylint: disable=no-self-argument,no-method-argument,no-init,inherit-non-class -# pylint: disable=too-few-public-methods @six.add_metaclass(abc.ABCMeta) @@ -372,7 +372,6 @@ class IInstaller(IPlugin): class IDisplay(zope.interface.Interface): """Generic display.""" - # pylint: disable=too-many-arguments # see https://github.com/certbot/certbot/issues/3915 def notification(message, pause, wrap=True, force_interactive=False): @@ -534,6 +533,62 @@ class IReporter(zope.interface.Interface): """Prints messages to the user and clears the message queue.""" +@six.add_metaclass(abc.ABCMeta) +class RenewableCert(object): + """Interface to a certificate lineage.""" + + @abc.abstractproperty + def cert_path(self): + """Path to the certificate file. + + :rtype: str + + """ + + @abc.abstractproperty + def key_path(self): + """Path to the private key file. + + :rtype: str + + """ + + @abc.abstractproperty + def chain_path(self): + """Path to the certificate chain file. + + :rtype: str + + """ + + @abc.abstractproperty + def fullchain_path(self): + """Path to the full chain file. + + The full chain is the certificate file plus the chain file. + + :rtype: str + + """ + + @abc.abstractproperty + def lineagename(self): + """Name given to the certificate lineage. + + :rtype: str + + """ + + @abc.abstractmethod + def names(self): + """What are the subject names of this certificate? + + :returns: the subject names + :rtype: `list` of `str` + :raises .CertStorageError: if could not find cert file. + + """ + # Updater interfaces # # When "certbot renew" is run, Certbot will iterate over each lineage and check @@ -572,7 +627,7 @@ class GenericUpdater(object): This method is called once for each lineage. :param lineage: Certificate lineage object - :type lineage: storage.RenewableCert + :type lineage: RenewableCert """ @@ -601,6 +656,6 @@ class RenewDeployer(object): This method is called once for each lineage renewed :param lineage: Certificate lineage object - :type lineage: storage.RenewableCert + :type lineage: RenewableCert """ diff --git a/certbot/certbot/main.py b/certbot/certbot/main.py new file mode 100644 index 000000000..b2fb1dbb7 --- /dev/null +++ b/certbot/certbot/main.py @@ -0,0 +1,15 @@ +"""Certbot main public entry point.""" +from certbot._internal import main as internal_main + + +def main(cli_args=None): + """Run Certbot. + + :param cli_args: command line to Certbot, defaults to ``sys.argv[1:]`` + :type cli_args: `list` of `str` + + :returns: value for `sys.exit` about the exit status of Certbot + :rtype: `str` or `int` or `None` + + """ + return internal_main.main(cli_args) diff --git a/certbot/plugins/__init__.py b/certbot/certbot/plugins/__init__.py similarity index 100% rename from certbot/plugins/__init__.py rename to certbot/certbot/plugins/__init__.py diff --git a/certbot/plugins/common.py b/certbot/certbot/plugins/common.py similarity index 99% rename from certbot/plugins/common.py rename to certbot/certbot/plugins/common.py index 843e27a1b..6fa1e76f8 100644 --- a/certbot/plugins/common.py +++ b/certbot/certbot/plugins/common.py @@ -6,21 +6,19 @@ import sys import tempfile import warnings +from josepy import util as jose_util import pkg_resources import zope.interface -from josepy import util as jose_util - from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - from certbot import achallenges # pylint: disable=unused-import -from certbot._internal import constants from certbot import crypto_util from certbot import errors from certbot import interfaces from certbot import reverter -from certbot.compat import os +from certbot._internal import constants from certbot.compat import filesystem +from certbot.compat import os from certbot.plugins.storage import PluginStorage logger = logging.getLogger(__name__) @@ -35,6 +33,7 @@ def dest_namespace(name): """ArgumentParser dest namespace (prefix of all destinations).""" return name.replace("-", "_") + "_" + private_ips_regex = re.compile( r"(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|" r"(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)") @@ -296,7 +295,7 @@ class Addr(object): # appended to the end append_to_end = True continue - elif len(block) > 1: + if len(block) > 1: # remove leading zeros block = block.lstrip("0") if not append_to_end: @@ -375,9 +374,9 @@ def install_version_controlled_file(dest_path, digest_path, src_path, all_hashes active_file_digest = crypto_util.sha256sum(dest_path) if active_file_digest == current_hash: # already up to date return - elif active_file_digest in all_hashes: # safe to update + if active_file_digest in all_hashes: # safe to update _install_current_file() - else: # has been manually modified, not safe to update + else: # has been manually modified, not safe to update # did they modify the current version or an old version? if os.path.isfile(digest_path): with open(digest_path, "r") as f: diff --git a/certbot/plugins/dns_common.py b/certbot/certbot/plugins/dns_common.py similarity index 98% rename from certbot/plugins/dns_common.py rename to certbot/certbot/plugins/dns_common.py index 931778b07..d31266434 100644 --- a/certbot/plugins/dns_common.py +++ b/certbot/certbot/plugins/dns_common.py @@ -8,7 +8,6 @@ import configobj import zope.interface from acme import challenges - from certbot import errors from certbot import interfaces from certbot.compat import filesystem @@ -198,8 +197,7 @@ class DNSAuthenticator(common.Plugin): if code == display_util.OK: return response - else: - raise errors.PluginError('{0} required to proceed.'.format(label)) + raise errors.PluginError('{0} required to proceed.'.format(label)) @staticmethod def _prompt_for_file(label, validator=None): @@ -232,8 +230,7 @@ class DNSAuthenticator(common.Plugin): if code == display_util.OK: return response - else: - raise errors.PluginError('{0} required to proceed.'.format(label)) + raise errors.PluginError('{0} required to proceed.'.format(label)) class CredentialsConfiguration(object): diff --git a/certbot/plugins/dns_common_lexicon.py b/certbot/certbot/plugins/dns_common_lexicon.py similarity index 92% rename from certbot/plugins/dns_common_lexicon.py rename to certbot/certbot/plugins/dns_common_lexicon.py index 2c82db030..3e28a291b 100644 --- a/certbot/plugins/dns_common_lexicon.py +++ b/certbot/certbot/plugins/dns_common_lexicon.py @@ -1,9 +1,12 @@ """Common code for DNS Authenticator Plugins built on Lexicon.""" import logging -from requests.exceptions import HTTPError, RequestException +from requests.exceptions import HTTPError +from requests.exceptions import RequestException -from acme.magic_typing import Union, Dict, Any # pylint: disable=unused-import,no-name-in-module +from acme.magic_typing import Any # 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 Union # pylint: disable=unused-import, no-name-in-module from certbot import errors from certbot.plugins import dns_common @@ -97,7 +100,7 @@ class LexiconClient(object): result = self._handle_general_error(e, domain_name) if result: - raise result + raise result # pylint: disable=raising-bad-type raise errors.PluginError('Unable to determine zone identifier for {0} using zone names: {1}' .format(domain, domain_name_guesses)) diff --git a/certbot/plugins/dns_test_common.py b/certbot/certbot/plugins/dns_test_common.py similarity index 89% rename from certbot/plugins/dns_test_common.py rename to certbot/certbot/plugins/dns_test_common.py index 0fc0c9a71..9ef76c2c3 100644 --- a/certbot/plugins/dns_test_common.py +++ b/certbot/certbot/plugins/dns_test_common.py @@ -6,7 +6,6 @@ import mock import six from acme import challenges - from certbot import achallenges from certbot.compat import filesystem from certbot.tests import acme_util @@ -29,18 +28,14 @@ class BaseAuthenticatorTest(object): challb=acme_util.DNS01, domain=DOMAIN, account_key=KEY) def test_more_info(self): - # pylint: disable=no-member - self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) + self.assertTrue(isinstance(self.auth.more_info(), six.string_types)) # pylint: disable=no-member def test_get_chall_pref(self): - # pylint: disable=no-member - self.assertEqual(self.auth.get_chall_pref(None), [challenges.DNS01]) + self.assertEqual(self.auth.get_chall_pref(None), [challenges.DNS01]) # pylint: disable=no-member def test_parser_arguments(self): m = mock.MagicMock() - - # pylint: disable=no-member - self.auth.add_parser_arguments(m) + self.auth.add_parser_arguments(m) # pylint: disable=no-member m.assert_any_call('propagation-seconds', type=int, default=mock.ANY, help=mock.ANY) diff --git a/certbot/plugins/dns_test_common_lexicon.py b/certbot/certbot/plugins/dns_test_common_lexicon.py similarity index 98% rename from certbot/plugins/dns_test_common_lexicon.py rename to certbot/certbot/plugins/dns_test_common_lexicon.py index a221cf1bf..c77d6da9e 100644 --- a/certbot/plugins/dns_test_common_lexicon.py +++ b/certbot/certbot/plugins/dns_test_common_lexicon.py @@ -2,7 +2,8 @@ import josepy as jose import mock -from requests.exceptions import HTTPError, RequestException +from requests.exceptions import HTTPError +from requests.exceptions import RequestException from certbot import errors from certbot.plugins import dns_test_common diff --git a/certbot/plugins/enhancements.py b/certbot/certbot/plugins/enhancements.py similarity index 89% rename from certbot/plugins/enhancements.py rename to certbot/certbot/plugins/enhancements.py index 8896c1a98..f8d9db7dc 100644 --- a/certbot/plugins/enhancements.py +++ b/certbot/certbot/plugins/enhancements.py @@ -1,11 +1,13 @@ """New interface style Certbot enhancements""" import abc + import six +from acme.magic_typing import Any # 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 certbot._internal import constants -from acme.magic_typing import Dict, List, Any # pylint: disable=unused-import, no-name-in-module - ENHANCEMENTS = ["redirect", "ensure-http-header", "ocsp-stapling"] """List of possible :class:`certbot.interfaces.IInstaller` enhancements. @@ -62,7 +64,7 @@ def enable(lineage, domains, installer, config): Run enable method for each requested enhancement that is supported. :param lineage: Certificate lineage object - :type lineage: certbot._internal.storage.RenewableCert + :type lineage: certbot.interfaces.RenewableCert :param domains: List of domains in certificate to enhance :type domains: str @@ -78,9 +80,9 @@ def enable(lineage, domains, installer, config): def populate_cli(add): """ - Populates the command line flags for certbot.cli.HelpfulParser + Populates the command line flags for certbot._internal.cli.HelpfulParser - :param add: Add function of certbot.cli.HelpfulParser + :param add: Add function of certbot._internal.cli.HelpfulParser :type add: func """ for enh in _INDEX: @@ -123,7 +125,7 @@ class AutoHSTSEnhancement(object): Implementation of this method should increase the max-age value. :param lineage: Certificate lineage object - :type lineage: certbot._internal.storage.RenewableCert + :type lineage: certbot.interfaces.RenewableCert .. note:: prepare() method inherited from `interfaces.IPlugin` might need to be called manually within implementation of this interface method @@ -137,7 +139,7 @@ class AutoHSTSEnhancement(object): Long max-age value should be set in implementation of this method. :param lineage: Certificate lineage object - :type lineage: certbot._internal.storage.RenewableCert + :type lineage: certbot.interfaces.RenewableCert """ @abc.abstractmethod @@ -148,7 +150,7 @@ class AutoHSTSEnhancement(object): over the subsequent runs of Certbot renew. :param lineage: Certificate lineage object - :type lineage: certbot._internal.storage.RenewableCert + :type lineage: certbot.interfaces.RenewableCert :param domains: List of domains in certificate to enhance :type domains: str diff --git a/certbot/plugins/storage.py b/certbot/certbot/plugins/storage.py similarity index 95% rename from certbot/plugins/storage.py rename to certbot/certbot/plugins/storage.py index 294dfa0e8..7956295d2 100644 --- a/certbot/plugins/storage.py +++ b/certbot/certbot/plugins/storage.py @@ -2,11 +2,11 @@ import json import logging -from acme.magic_typing import Any, Dict # pylint: disable=unused-import, no-name-in-module - +from acme.magic_typing import Any # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module from certbot import errors -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot/plugins/util.py b/certbot/certbot/plugins/util.py similarity index 100% rename from certbot/plugins/util.py rename to certbot/certbot/plugins/util.py diff --git a/certbot/reverter.py b/certbot/certbot/reverter.py similarity index 100% rename from certbot/reverter.py rename to certbot/certbot/reverter.py index 9118fef94..47a77c80a 100644 --- a/certbot/reverter.py +++ b/certbot/certbot/reverter.py @@ -9,11 +9,11 @@ import traceback import six -from certbot._internal import constants from certbot import errors from certbot import util -from certbot.compat import os +from certbot._internal import constants from certbot.compat import filesystem +from certbot.compat import os logger = logging.getLogger(__name__) diff --git a/certbot/ssl-dhparams.pem b/certbot/certbot/ssl-dhparams.pem similarity index 100% rename from certbot/ssl-dhparams.pem rename to certbot/certbot/ssl-dhparams.pem diff --git a/certbot/certbot/tests/__init__.py b/certbot/certbot/tests/__init__.py new file mode 100644 index 000000000..82290ca0b --- /dev/null +++ b/certbot/certbot/tests/__init__.py @@ -0,0 +1 @@ +"""Utilities for running Certbot tests""" diff --git a/certbot/tests/acme_util.py b/certbot/certbot/tests/acme_util.py similarity index 99% rename from certbot/tests/acme_util.py rename to certbot/certbot/tests/acme_util.py index c88fcd706..3d560dcbc 100644 --- a/certbot/tests/acme_util.py +++ b/certbot/certbot/tests/acme_util.py @@ -6,12 +6,9 @@ import six from acme import challenges from acme import messages - from certbot._internal import auth_handler - from certbot.tests import util - JWK = jose.JWK.load(util.load_vector('rsa512_key.pem')) KEY = util.load_rsa_private_key('rsa512_key.pem') diff --git a/certbot/tests/testdata/README b/certbot/certbot/tests/testdata/README similarity index 100% rename from certbot/tests/testdata/README rename to certbot/certbot/tests/testdata/README diff --git a/certbot/tests/testdata/cert-5sans_512.pem b/certbot/certbot/tests/testdata/cert-5sans_512.pem similarity index 100% rename from certbot/tests/testdata/cert-5sans_512.pem rename to certbot/certbot/tests/testdata/cert-5sans_512.pem diff --git a/certbot/tests/testdata/cert-nosans_nistp256.pem b/certbot/certbot/tests/testdata/cert-nosans_nistp256.pem similarity index 100% rename from certbot/tests/testdata/cert-nosans_nistp256.pem rename to certbot/certbot/tests/testdata/cert-nosans_nistp256.pem diff --git a/certbot/tests/testdata/cert-san_512.pem b/certbot/certbot/tests/testdata/cert-san_512.pem similarity index 100% rename from certbot/tests/testdata/cert-san_512.pem rename to certbot/certbot/tests/testdata/cert-san_512.pem diff --git a/certbot/tests/testdata/cert_2048.pem b/certbot/certbot/tests/testdata/cert_2048.pem similarity index 100% rename from certbot/tests/testdata/cert_2048.pem rename to certbot/certbot/tests/testdata/cert_2048.pem diff --git a/certbot/tests/testdata/cert_512.pem b/certbot/certbot/tests/testdata/cert_512.pem similarity index 100% rename from certbot/tests/testdata/cert_512.pem rename to certbot/certbot/tests/testdata/cert_512.pem diff --git a/certbot/tests/testdata/cert_512_bad.pem b/certbot/certbot/tests/testdata/cert_512_bad.pem similarity index 100% rename from certbot/tests/testdata/cert_512_bad.pem rename to certbot/certbot/tests/testdata/cert_512_bad.pem diff --git a/certbot/tests/testdata/cert_fullchain_2048.pem b/certbot/certbot/tests/testdata/cert_fullchain_2048.pem similarity index 100% rename from certbot/tests/testdata/cert_fullchain_2048.pem rename to certbot/certbot/tests/testdata/cert_fullchain_2048.pem diff --git a/certbot/tests/testdata/cli.ini b/certbot/certbot/tests/testdata/cli.ini similarity index 100% rename from certbot/tests/testdata/cli.ini rename to certbot/certbot/tests/testdata/cli.ini diff --git a/certbot/tests/testdata/csr-6sans_512.conf b/certbot/certbot/tests/testdata/csr-6sans_512.conf similarity index 100% rename from certbot/tests/testdata/csr-6sans_512.conf rename to certbot/certbot/tests/testdata/csr-6sans_512.conf diff --git a/certbot/tests/testdata/csr-6sans_512.pem b/certbot/certbot/tests/testdata/csr-6sans_512.pem similarity index 100% rename from certbot/tests/testdata/csr-6sans_512.pem rename to certbot/certbot/tests/testdata/csr-6sans_512.pem diff --git a/certbot/tests/testdata/csr-nonames_512.pem b/certbot/certbot/tests/testdata/csr-nonames_512.pem similarity index 100% rename from certbot/tests/testdata/csr-nonames_512.pem rename to certbot/certbot/tests/testdata/csr-nonames_512.pem diff --git a/certbot/tests/testdata/csr-nosans_512.conf b/certbot/certbot/tests/testdata/csr-nosans_512.conf similarity index 100% rename from certbot/tests/testdata/csr-nosans_512.conf rename to certbot/certbot/tests/testdata/csr-nosans_512.conf diff --git a/certbot/tests/testdata/csr-nosans_512.pem b/certbot/certbot/tests/testdata/csr-nosans_512.pem similarity index 100% rename from certbot/tests/testdata/csr-nosans_512.pem rename to certbot/certbot/tests/testdata/csr-nosans_512.pem diff --git a/certbot/tests/testdata/csr-nosans_nistp256.pem b/certbot/certbot/tests/testdata/csr-nosans_nistp256.pem similarity index 100% rename from certbot/tests/testdata/csr-nosans_nistp256.pem rename to certbot/certbot/tests/testdata/csr-nosans_nistp256.pem diff --git a/certbot/tests/testdata/csr-san_512.pem b/certbot/certbot/tests/testdata/csr-san_512.pem similarity index 100% rename from certbot/tests/testdata/csr-san_512.pem rename to certbot/certbot/tests/testdata/csr-san_512.pem diff --git a/certbot/tests/testdata/csr_512.der b/certbot/certbot/tests/testdata/csr_512.der similarity index 100% rename from certbot/tests/testdata/csr_512.der rename to certbot/certbot/tests/testdata/csr_512.der diff --git a/certbot/tests/testdata/csr_512.pem b/certbot/certbot/tests/testdata/csr_512.pem similarity index 100% rename from certbot/tests/testdata/csr_512.pem rename to certbot/certbot/tests/testdata/csr_512.pem diff --git a/certbot/tests/testdata/nistp256_key.pem b/certbot/certbot/tests/testdata/nistp256_key.pem similarity index 100% rename from certbot/tests/testdata/nistp256_key.pem rename to certbot/certbot/tests/testdata/nistp256_key.pem diff --git a/certbot/tests/testdata/ocsp_certificate.pem b/certbot/certbot/tests/testdata/ocsp_certificate.pem similarity index 100% rename from certbot/tests/testdata/ocsp_certificate.pem rename to certbot/certbot/tests/testdata/ocsp_certificate.pem diff --git a/certbot/tests/testdata/ocsp_issuer_certificate.pem b/certbot/certbot/tests/testdata/ocsp_issuer_certificate.pem similarity index 100% rename from certbot/tests/testdata/ocsp_issuer_certificate.pem rename to certbot/certbot/tests/testdata/ocsp_issuer_certificate.pem diff --git a/certbot/tests/testdata/ocsp_responder_certificate.pem b/certbot/certbot/tests/testdata/ocsp_responder_certificate.pem similarity index 100% rename from certbot/tests/testdata/ocsp_responder_certificate.pem rename to certbot/certbot/tests/testdata/ocsp_responder_certificate.pem diff --git a/certbot/tests/testdata/os-release b/certbot/certbot/tests/testdata/os-release similarity index 100% rename from certbot/tests/testdata/os-release rename to certbot/certbot/tests/testdata/os-release diff --git a/certbot/tests/testdata/rsa2048_key.pem b/certbot/certbot/tests/testdata/rsa2048_key.pem similarity index 100% rename from certbot/tests/testdata/rsa2048_key.pem rename to certbot/certbot/tests/testdata/rsa2048_key.pem diff --git a/certbot/tests/testdata/rsa256_key.pem b/certbot/certbot/tests/testdata/rsa256_key.pem similarity index 100% rename from certbot/tests/testdata/rsa256_key.pem rename to certbot/certbot/tests/testdata/rsa256_key.pem diff --git a/certbot/tests/testdata/rsa512_key.pem b/certbot/certbot/tests/testdata/rsa512_key.pem similarity index 100% rename from certbot/tests/testdata/rsa512_key.pem rename to certbot/certbot/tests/testdata/rsa512_key.pem diff --git a/certbot/tests/testdata/sample-archive/cert1.pem b/certbot/certbot/tests/testdata/sample-archive/cert1.pem similarity index 100% rename from certbot/tests/testdata/sample-archive/cert1.pem rename to certbot/certbot/tests/testdata/sample-archive/cert1.pem diff --git a/certbot/tests/testdata/sample-archive/chain1.pem b/certbot/certbot/tests/testdata/sample-archive/chain1.pem similarity index 100% rename from certbot/tests/testdata/sample-archive/chain1.pem rename to certbot/certbot/tests/testdata/sample-archive/chain1.pem diff --git a/certbot/tests/testdata/sample-archive/fullchain1.pem b/certbot/certbot/tests/testdata/sample-archive/fullchain1.pem similarity index 100% rename from certbot/tests/testdata/sample-archive/fullchain1.pem rename to certbot/certbot/tests/testdata/sample-archive/fullchain1.pem diff --git a/certbot/tests/testdata/sample-archive/privkey1.pem b/certbot/certbot/tests/testdata/sample-archive/privkey1.pem similarity index 100% rename from certbot/tests/testdata/sample-archive/privkey1.pem rename to certbot/certbot/tests/testdata/sample-archive/privkey1.pem diff --git a/certbot/tests/testdata/sample-renewal-ancient.conf b/certbot/certbot/tests/testdata/sample-renewal-ancient.conf similarity index 100% rename from certbot/tests/testdata/sample-renewal-ancient.conf rename to certbot/certbot/tests/testdata/sample-renewal-ancient.conf diff --git a/certbot/tests/testdata/sample-renewal.conf b/certbot/certbot/tests/testdata/sample-renewal.conf similarity index 100% rename from certbot/tests/testdata/sample-renewal.conf rename to certbot/certbot/tests/testdata/sample-renewal.conf diff --git a/certbot/tests/testdata/webrootconftest.ini b/certbot/certbot/tests/testdata/webrootconftest.ini similarity index 100% rename from certbot/tests/testdata/webrootconftest.ini rename to certbot/certbot/tests/testdata/webrootconftest.ini diff --git a/certbot/tests/util.py b/certbot/certbot/tests/util.py similarity index 97% rename from certbot/tests/util.py rename to certbot/certbot/tests/util.py index 00452fef9..02abe0a31 100644 --- a/certbot/tests/util.py +++ b/certbot/certbot/tests/util.py @@ -4,29 +4,30 @@ """ import logging +from multiprocessing import Event +from multiprocessing import Process import shutil import sys import tempfile import unittest -from multiprocessing import Process, Event -import OpenSSL +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization import josepy as jose import mock +import OpenSSL import pkg_resources import six from six.moves import reload_module # pylint: disable=import-error -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import serialization -from certbot import configuration -from certbot._internal import constants from certbot import interfaces +from certbot import util +from certbot._internal import configuration +from certbot._internal import constants from certbot._internal import lock from certbot._internal import storage -from certbot import util -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os from certbot.display import util as display_util @@ -56,8 +57,7 @@ def _guess_loader(filename, loader_pem, loader_der): return loader_pem elif ext.lower() == '.der': return loader_der - else: # pragma: no cover - raise ValueError("Loader could not be recognized based on extension") + raise ValueError("Loader could not be recognized based on extension") # pragma: no cover def load_cert(*names): @@ -234,8 +234,7 @@ class FreezableMock(object): if self._frozen: if name in self._frozen_set: raise AttributeError('Cannot change frozen attribute ' + name) - else: - return setattr(self._mock, name, value) + return setattr(self._mock, name, value) if name != '_frozen_set': self._frozen_set.add(name) @@ -249,7 +248,7 @@ class FreezableMock(object): def _create_get_utility_mock(): display = FreezableMock() # Use pylint code for disable to keep on single line under line length limit - for name in interfaces.IDisplay.names(): # pylint: disable=no-member,E1120 + for name in interfaces.IDisplay.names(): # pylint: E1120 if name != 'notification': frozen_mock = FreezableMock(frozen=True, func=_assert_valid_call) setattr(display, name, frozen_mock) @@ -274,7 +273,7 @@ def _create_get_utility_mock_with_stdout(stdout): display = FreezableMock() # Use pylint code for disable to keep on single line under line length limit - for name in interfaces.IDisplay.names(): # pylint: disable=no-member,E1120 + for name in interfaces.IDisplay.names(): # pylint: E1120 if name == 'notification': frozen_mock = FreezableMock(frozen=True, func=_write_msg) diff --git a/certbot/util.py b/certbot/certbot/util.py similarity index 97% rename from certbot/util.py rename to certbot/certbot/util.py index 5d8aa8f22..0a47cd87a 100644 --- a/certbot/util.py +++ b/certbot/certbot/util.py @@ -1,10 +1,10 @@ """Utilities for all Certbot.""" +# distutils.version under virtualenv confuses pylint +# For more info, see: https://github.com/PyCQA/pylint/issues/73 import argparse import atexit import collections from collections import OrderedDict -# distutils.version under virtualenv confuses pylint -# For more info, see: https://github.com/PyCQA/pylint/issues/73 import distutils.version # pylint: disable=import-error,no-name-in-module import errno import logging @@ -17,16 +17,16 @@ import sys import configargparse import six -from acme.magic_typing import Tuple, Union # pylint: disable=unused-import, no-name-in-module - -from certbot._internal import constants +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 certbot import errors +from certbot._internal import constants from certbot._internal import lock -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os if sys.platform.startswith('linux'): - import distro + import distro # pylint: disable=import-error _USE_DISTRO = True else: _USE_DISTRO = False @@ -105,10 +105,9 @@ def exe_exists(exe): path, _ = os.path.split(exe) if path: return filesystem.is_executable(exe) - else: - for path in os.environ["PATH"].split(os.pathsep): - if filesystem.is_executable(os.path.join(path, exe)): - return True + for path in os.environ["PATH"].split(os.pathsep): + if filesystem.is_executable(os.path.join(path, exe)): + return True return False @@ -436,7 +435,6 @@ def add_deprecated_argument(add_argument, argument_name, nargs): # In version 0.12.0 ACTION_TYPES_THAT_DONT_NEED_A_VALUE was # changed from a set to a tuple. if isinstance(configargparse.ACTION_TYPES_THAT_DONT_NEED_A_VALUE, set): - # pylint: disable=no-member configargparse.ACTION_TYPES_THAT_DONT_NEED_A_VALUE.add( _ShowWarning) else: @@ -537,7 +535,7 @@ def enforce_domain_sanity(domain): for l in labels: if not l: raise errors.ConfigurationError("{0} it contains an empty label.".format(msg)) - elif len(l) > 63: + if len(l) > 63: raise errors.ConfigurationError("{0} label {1} is too long.".format(msg, l)) return domain @@ -571,7 +569,6 @@ def get_strict_version(normalized): """ # strict version ending with "a" and a number designates a pre-release - # pylint: disable=no-member return distutils.version.StrictVersion(normalized.replace(".dev", "a")) diff --git a/certbot-apache/docs/.gitignore b/certbot/docs/.gitignore similarity index 100% rename from certbot-apache/docs/.gitignore rename to certbot/docs/.gitignore diff --git a/docs/Makefile b/certbot/docs/Makefile similarity index 100% rename from docs/Makefile rename to certbot/docs/Makefile diff --git a/certbot-apache/docs/_static/.gitignore b/certbot/docs/_static/.gitignore similarity index 100% rename from certbot-apache/docs/_static/.gitignore rename to certbot/docs/_static/.gitignore diff --git a/docs/_templates/footer.html b/certbot/docs/_templates/footer.html similarity index 100% rename from docs/_templates/footer.html rename to certbot/docs/_templates/footer.html diff --git a/certbot-apache/docs/api.rst b/certbot/docs/api.rst similarity index 69% rename from certbot-apache/docs/api.rst rename to certbot/docs/api.rst index 8668ec5d8..9c8b2f1fe 100644 --- a/certbot-apache/docs/api.rst +++ b/certbot/docs/api.rst @@ -3,6 +3,6 @@ API Documentation ================= .. toctree:: - :glob: + :maxdepth: 4 - api/** + api/certbot diff --git a/certbot/docs/api/certbot.achallenges.rst b/certbot/docs/api/certbot.achallenges.rst new file mode 100644 index 000000000..3fd2f2a42 --- /dev/null +++ b/certbot/docs/api/certbot.achallenges.rst @@ -0,0 +1,7 @@ +certbot.achallenges module +========================== + +.. automodule:: certbot.achallenges + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.compat.filesystem.rst b/certbot/docs/api/certbot.compat.filesystem.rst new file mode 100644 index 000000000..d4f1e2fe0 --- /dev/null +++ b/certbot/docs/api/certbot.compat.filesystem.rst @@ -0,0 +1,7 @@ +certbot.compat.filesystem module +================================ + +.. automodule:: certbot.compat.filesystem + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.compat.misc.rst b/certbot/docs/api/certbot.compat.misc.rst new file mode 100644 index 000000000..35c2913e7 --- /dev/null +++ b/certbot/docs/api/certbot.compat.misc.rst @@ -0,0 +1,7 @@ +certbot.compat.misc module +========================== + +.. automodule:: certbot.compat.misc + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.compat.os.rst b/certbot/docs/api/certbot.compat.os.rst new file mode 100644 index 000000000..3a4c9fe47 --- /dev/null +++ b/certbot/docs/api/certbot.compat.os.rst @@ -0,0 +1,7 @@ +certbot.compat.os module +======================== + +.. automodule:: certbot.compat.os + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.compat.rst b/certbot/docs/api/certbot.compat.rst new file mode 100644 index 000000000..f6f2b3739 --- /dev/null +++ b/certbot/docs/api/certbot.compat.rst @@ -0,0 +1,17 @@ +certbot.compat package +====================== + +.. automodule:: certbot.compat + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +.. toctree:: + + certbot.compat.filesystem + certbot.compat.misc + certbot.compat.os + diff --git a/certbot/docs/api/certbot.crypto_util.rst b/certbot/docs/api/certbot.crypto_util.rst new file mode 100644 index 000000000..34aa665b9 --- /dev/null +++ b/certbot/docs/api/certbot.crypto_util.rst @@ -0,0 +1,7 @@ +certbot.crypto\_util module +=========================== + +.. automodule:: certbot.crypto_util + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.display.ops.rst b/certbot/docs/api/certbot.display.ops.rst new file mode 100644 index 000000000..544b0dad3 --- /dev/null +++ b/certbot/docs/api/certbot.display.ops.rst @@ -0,0 +1,7 @@ +certbot.display.ops module +========================== + +.. automodule:: certbot.display.ops + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.display.rst b/certbot/docs/api/certbot.display.rst new file mode 100644 index 000000000..04bc68b07 --- /dev/null +++ b/certbot/docs/api/certbot.display.rst @@ -0,0 +1,16 @@ +certbot.display package +======================= + +.. automodule:: certbot.display + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +.. toctree:: + + certbot.display.ops + certbot.display.util + diff --git a/certbot/docs/api/certbot.display.util.rst b/certbot/docs/api/certbot.display.util.rst new file mode 100644 index 000000000..22b59dc98 --- /dev/null +++ b/certbot/docs/api/certbot.display.util.rst @@ -0,0 +1,7 @@ +certbot.display.util module +=========================== + +.. automodule:: certbot.display.util + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.errors.rst b/certbot/docs/api/certbot.errors.rst new file mode 100644 index 000000000..731b7695d --- /dev/null +++ b/certbot/docs/api/certbot.errors.rst @@ -0,0 +1,7 @@ +certbot.errors module +===================== + +.. automodule:: certbot.errors + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.interfaces.rst b/certbot/docs/api/certbot.interfaces.rst new file mode 100644 index 000000000..2665aaa01 --- /dev/null +++ b/certbot/docs/api/certbot.interfaces.rst @@ -0,0 +1,7 @@ +certbot.interfaces module +========================= + +.. automodule:: certbot.interfaces + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.main.rst b/certbot/docs/api/certbot.main.rst new file mode 100644 index 000000000..ce0539f5c --- /dev/null +++ b/certbot/docs/api/certbot.main.rst @@ -0,0 +1,7 @@ +certbot.main module +=================== + +.. automodule:: certbot.main + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.plugins.common.rst b/certbot/docs/api/certbot.plugins.common.rst new file mode 100644 index 000000000..e94b2d12e --- /dev/null +++ b/certbot/docs/api/certbot.plugins.common.rst @@ -0,0 +1,7 @@ +certbot.plugins.common module +============================= + +.. automodule:: certbot.plugins.common + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.plugins.dns_common.rst b/certbot/docs/api/certbot.plugins.dns_common.rst new file mode 100644 index 000000000..36c7a6428 --- /dev/null +++ b/certbot/docs/api/certbot.plugins.dns_common.rst @@ -0,0 +1,7 @@ +certbot.plugins.dns\_common module +================================== + +.. automodule:: certbot.plugins.dns_common + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.plugins.dns_common_lexicon.rst b/certbot/docs/api/certbot.plugins.dns_common_lexicon.rst new file mode 100644 index 000000000..1a961accd --- /dev/null +++ b/certbot/docs/api/certbot.plugins.dns_common_lexicon.rst @@ -0,0 +1,7 @@ +certbot.plugins.dns\_common\_lexicon module +=========================================== + +.. automodule:: certbot.plugins.dns_common_lexicon + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.plugins.dns_test_common.rst b/certbot/docs/api/certbot.plugins.dns_test_common.rst new file mode 100644 index 000000000..69e672f0a --- /dev/null +++ b/certbot/docs/api/certbot.plugins.dns_test_common.rst @@ -0,0 +1,7 @@ +certbot.plugins.dns\_test\_common module +======================================== + +.. automodule:: certbot.plugins.dns_test_common + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.plugins.dns_test_common_lexicon.rst b/certbot/docs/api/certbot.plugins.dns_test_common_lexicon.rst new file mode 100644 index 000000000..92d516c99 --- /dev/null +++ b/certbot/docs/api/certbot.plugins.dns_test_common_lexicon.rst @@ -0,0 +1,7 @@ +certbot.plugins.dns\_test\_common\_lexicon module +================================================= + +.. automodule:: certbot.plugins.dns_test_common_lexicon + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.plugins.enhancements.rst b/certbot/docs/api/certbot.plugins.enhancements.rst new file mode 100644 index 000000000..16db737c7 --- /dev/null +++ b/certbot/docs/api/certbot.plugins.enhancements.rst @@ -0,0 +1,7 @@ +certbot.plugins.enhancements module +=================================== + +.. automodule:: certbot.plugins.enhancements + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.plugins.rst b/certbot/docs/api/certbot.plugins.rst new file mode 100644 index 000000000..517a209e6 --- /dev/null +++ b/certbot/docs/api/certbot.plugins.rst @@ -0,0 +1,22 @@ +certbot.plugins package +======================= + +.. automodule:: certbot.plugins + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +.. toctree:: + + certbot.plugins.common + certbot.plugins.dns_common + certbot.plugins.dns_common_lexicon + certbot.plugins.dns_test_common + certbot.plugins.dns_test_common_lexicon + certbot.plugins.enhancements + certbot.plugins.storage + certbot.plugins.util + diff --git a/certbot/docs/api/certbot.plugins.storage.rst b/certbot/docs/api/certbot.plugins.storage.rst new file mode 100644 index 000000000..9ed0fe724 --- /dev/null +++ b/certbot/docs/api/certbot.plugins.storage.rst @@ -0,0 +1,7 @@ +certbot.plugins.storage module +============================== + +.. automodule:: certbot.plugins.storage + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.plugins.util.rst b/certbot/docs/api/certbot.plugins.util.rst new file mode 100644 index 000000000..c5453564e --- /dev/null +++ b/certbot/docs/api/certbot.plugins.util.rst @@ -0,0 +1,7 @@ +certbot.plugins.util module +=========================== + +.. automodule:: certbot.plugins.util + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.reverter.rst b/certbot/docs/api/certbot.reverter.rst new file mode 100644 index 000000000..002b75360 --- /dev/null +++ b/certbot/docs/api/certbot.reverter.rst @@ -0,0 +1,7 @@ +certbot.reverter module +======================= + +.. automodule:: certbot.reverter + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.rst b/certbot/docs/api/certbot.rst new file mode 100644 index 000000000..6f5b4b403 --- /dev/null +++ b/certbot/docs/api/certbot.rst @@ -0,0 +1,31 @@ +certbot package +=============== + +.. automodule:: certbot + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + + certbot.compat + certbot.display + certbot.plugins + certbot.tests + +Submodules +---------- + +.. toctree:: + + certbot.achallenges + certbot.crypto_util + certbot.errors + certbot.interfaces + certbot.main + certbot.reverter + certbot.util + diff --git a/certbot/docs/api/certbot.tests.acme_util.rst b/certbot/docs/api/certbot.tests.acme_util.rst new file mode 100644 index 000000000..908397596 --- /dev/null +++ b/certbot/docs/api/certbot.tests.acme_util.rst @@ -0,0 +1,7 @@ +certbot.tests.acme\_util module +=============================== + +.. automodule:: certbot.tests.acme_util + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.tests.rst b/certbot/docs/api/certbot.tests.rst new file mode 100644 index 000000000..336f0eabc --- /dev/null +++ b/certbot/docs/api/certbot.tests.rst @@ -0,0 +1,16 @@ +certbot.tests package +===================== + +.. automodule:: certbot.tests + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +.. toctree:: + + certbot.tests.acme_util + certbot.tests.util + diff --git a/certbot/docs/api/certbot.tests.util.rst b/certbot/docs/api/certbot.tests.util.rst new file mode 100644 index 000000000..3f0335849 --- /dev/null +++ b/certbot/docs/api/certbot.tests.util.rst @@ -0,0 +1,7 @@ +certbot.tests.util module +========================= + +.. automodule:: certbot.tests.util + :members: + :undoc-members: + :show-inheritance: diff --git a/certbot/docs/api/certbot.util.rst b/certbot/docs/api/certbot.util.rst new file mode 100644 index 000000000..11cb33b09 --- /dev/null +++ b/certbot/docs/api/certbot.util.rst @@ -0,0 +1,7 @@ +certbot.util module +=================== + +.. automodule:: certbot.util + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/challenges.rst b/certbot/docs/challenges.rst similarity index 100% rename from docs/challenges.rst rename to certbot/docs/challenges.rst diff --git a/docs/ciphers.rst b/certbot/docs/ciphers.rst similarity index 100% rename from docs/ciphers.rst rename to certbot/docs/ciphers.rst diff --git a/docs/cli-help.txt b/certbot/docs/cli-help.txt similarity index 98% rename from docs/cli-help.txt rename to certbot/docs/cli-help.txt index efade498c..9b463820a 100644 --- a/docs/cli-help.txt +++ b/certbot/docs/cli-help.txt @@ -24,8 +24,8 @@ obtain, install, and renew certificates: manage certificates: certificates Display information about certificates you have from Certbot - revoke Revoke a certificate (supply --cert-path or --cert-name) - delete Delete a certificate + revoke Revoke a certificate (supply --cert-name or --cert-path) + delete Delete a certificate (supply --cert-name) manage your account: register Create an ACME account @@ -113,12 +113,12 @@ optional arguments: case, and to know when to deprecate support for past Python versions and flags. If you wish to hide this information from the Let's Encrypt server, set this to - "". (default: CertbotACMEClient/0.40.1 - (certbot(-auto); OS_NAME OS_VERSION) Authenticator/XXX - Installer/YYY (SUBCOMMAND; flags: FLAGS) - Py/major.minor.patchlevel). The flags encoded in the - user agent are: --duplicate, --force-renew, --allow- - subset-of-names, -n, and whether any hooks are set. + "". (default: CertbotACMEClient/1.1.0 (certbot(-auto); + OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY + (SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel). + The flags encoded in the user agent are: --duplicate, + --force-renew, --allow-subset-of-names, -n, and + whether any hooks are set. --user-agent-comment USER_AGENT_COMMENT Add a comment to the default user agent string. May be used when repackaging Certbot or calling it from diff --git a/docs/conf.py b/certbot/docs/conf.py similarity index 99% rename from docs/conf.py rename to certbot/docs/conf.py index c72d1c1cf..1e57bc224 100644 --- a/docs/conf.py +++ b/certbot/docs/conf.py @@ -19,7 +19,6 @@ import sys import sphinx - here = os.path.abspath(os.path.dirname(__file__)) # read version number (and other metadata) from package init @@ -53,7 +52,7 @@ if sphinx.version_info >= (1, 6): extensions.append('sphinx.ext.imgconverter') 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'] diff --git a/docs/contributing.rst b/certbot/docs/contributing.rst similarity index 93% rename from docs/contributing.rst rename to certbot/docs/contributing.rst index cc0a74b43..e1289c849 100644 --- a/docs/contributing.rst +++ b/certbot/docs/contributing.rst @@ -36,29 +36,36 @@ run Certbot in Docker. You can find instructions for how to do this :ref:`here install dependencies and set up a virtual environment where you can run Certbot. +Install the OS system dependencies required to run Certbot. + +.. code-block:: shell + + # For APT-based distributions (e.g. Debian, Ubuntu ...) + sudo apt update + sudo apt install python3-dev python3-venv gcc libaugeas0 libssl-dev \ + libffi-dev ca-certificates openssl + # For RPM-based distributions (e.g. Fedora, CentOS ...) + # NB1: old distributions will use yum instead of dnf + # NB2: RHEL-based distributions use python3X-devel instead of python3-devel (e.g. python36-devel) + sudo dnf install python3-devel gcc augeas-libs openssl-devel libffi-devel \ + redhat-rpm-config ca-certificates openssl + +Set up the Python virtual environment that will host your Certbot local instance. + .. code-block:: shell cd certbot - ./certbot-auto --debug --os-packages-only - python tools/venv.py - -If you have Python3 available and want to use it, run the ``venv3.py`` script. - -.. code-block:: shell - python tools/venv3.py .. note:: You may need to repeat this when Certbot's dependencies change or when a new plugin is introduced. You can now run the copy of Certbot from git either by executing -``venv/bin/certbot``, or by activating the virtual environment. You can do the +``venv3/bin/certbot``, or by activating the virtual environment. You can do the latter by running: .. code-block:: shell - source venv/bin/activate - # or source venv3/bin/activate After running this command, ``certbot`` and development tools like ``ipdb``, @@ -293,6 +300,16 @@ configuration checkpoints and rollback. Writing your own plugin ~~~~~~~~~~~~~~~~~~~~~~~ +.. note:: The Certbot team is not currently accepting any new DNS plugins + because we want to rethink our approach to the challenge and resolve some + issues like `#6464 `_, + `#6503 `_, and `#6504 + `_ first. + + In the meantime, you're welcome to release it as a third-party plugin. See + `certbot-dns-ispconfig `_ + for one example of that. + Certbot client supports dynamic discovery of plugins through the `setuptools entry points`_ using the `certbot.plugins` group. This way you can, for example, create a custom implementation of @@ -321,12 +338,6 @@ plugins. It's technically possible to install third-party plugins into the virtualenv used by `certbot-auto`, but they will be wiped away when `certbot-auto` upgrades. -.. warning:: Please be aware though that as this client is still in a - developer-preview stage, the API may undergo a few changes. If you - believe the plugin will be beneficial to the community, please - consider submitting a pull request to the repo and we will update - it with any necessary API changes. - .. _`setuptools entry points`: http://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points @@ -402,7 +413,7 @@ Note that instead of just importing ``typing``, due to packaging issues, in Cert .. code-block:: python - from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module + from acme.magic_typing import Dict Also note that OpenSSL, which we rely on, has type definitions for crypto but not SSL. We use both. Those imports should look like this: @@ -524,7 +535,7 @@ This should generate documentation in the ``docs/_build/html`` directory. .. note:: If you skipped the "Getting Started" instructions above, - run ``pip install -e ".[docs]"`` to install Certbot's docs extras modules. + run ``pip install -e "certbot[docs]"`` to install Certbot's docs extras modules. .. _docker-dev: diff --git a/docs/index.rst b/certbot/docs/index.rst similarity index 100% rename from docs/index.rst rename to certbot/docs/index.rst diff --git a/docs/install.rst b/certbot/docs/install.rst similarity index 94% rename from docs/install.rst rename to certbot/docs/install.rst index 1e709e2ee..d21242367 100644 --- a/docs/install.rst +++ b/certbot/docs/install.rst @@ -41,7 +41,7 @@ client as root, either `letsencrypt-nosudo The Apache plugin currently requires an OS with augeas version 1.0; currently `it supports -`_ +`_ modern OSes based on Debian, Ubuntu, Fedora, SUSE, Gentoo and Darwin. @@ -70,11 +70,13 @@ The ``certbot-auto`` wrapper script installs Certbot, obtaining some dependencie from your web server OS and putting others in a python virtual environment. You can download and run it as follows:: - user@webserver:~$ wget https://dl.eff.org/certbot-auto - user@webserver:~$ sudo mv certbot-auto /usr/local/bin/certbot-auto - user@webserver:~$ sudo chown root /usr/local/bin/certbot-auto - user@webserver:~$ chmod 0755 /usr/local/bin/certbot-auto - user@webserver:~$ /usr/local/bin/certbot-auto --help + wget https://dl.eff.org/certbot-auto + sudo mv certbot-auto /usr/local/bin/certbot-auto + sudo chown root /usr/local/bin/certbot-auto + sudo chmod 0755 /usr/local/bin/certbot-auto + /usr/local/bin/certbot-auto --help + +To remove certbot-auto, just delete it and the files it places under /opt/eff.org, along with any cronjob or systemd timer you may have created. To check the integrity of the ``certbot-auto`` script, you can use these steps:: @@ -328,9 +330,9 @@ Installing from source Installation from source is only supported for developers and the whole process is described in the :doc:`contributing`. -.. warning:: Please do **not** use ``python setup.py install``, ``python pip - install .``, or ``easy_install .``. Please do **not** attempt the +.. warning:: Please do **not** use ``python certbot/setup.py install``, ``python pip + install certbot``, or ``easy_install certbot``. Please do **not** attempt the installation commands as superuser/root and/or without virtual environment, - e.g. ``sudo python setup.py install``, ``sudo pip install``, ``sudo + e.g. ``sudo python certbot/setup.py install``, ``sudo pip install``, ``sudo ./venv/bin/...``. These modes of operation might corrupt your operating system and are **not supported** by the Certbot team! diff --git a/docs/intro.rst b/certbot/docs/intro.rst similarity index 100% rename from docs/intro.rst rename to certbot/docs/intro.rst diff --git a/docs/make.bat b/certbot/docs/make.bat similarity index 100% rename from docs/make.bat rename to certbot/docs/make.bat diff --git a/docs/man/certbot.rst b/certbot/docs/man/certbot.rst similarity index 100% rename from docs/man/certbot.rst rename to certbot/docs/man/certbot.rst diff --git a/docs/packaging.rst b/certbot/docs/packaging.rst similarity index 100% rename from docs/packaging.rst rename to certbot/docs/packaging.rst diff --git a/docs/resources.rst b/certbot/docs/resources.rst similarity index 100% rename from docs/resources.rst rename to certbot/docs/resources.rst diff --git a/docs/using.rst b/certbot/docs/using.rst similarity index 99% rename from docs/using.rst rename to certbot/docs/using.rst index 83d824058..27ae826bd 100644 --- a/docs/using.rst +++ b/certbot/docs/using.rst @@ -58,8 +58,8 @@ standalone_ Y N | Uses a "standalone" webserver to obtain a certificate. | the only way to obtain wildcard certificates from Let's | Encrypt. manual_ Y N | Helps you obtain a certificate by giving you instructions to http-01_ (80) or - | perform domain validation yourself. Additionally allows you dns-01_ (53) - | to specify scripts to automate the validation task in a + | perform domain validation yourself. Additionally allows you dns-01_ (53) + | to specify scripts to automate the validation task in a | customized way. =========== ==== ==== =============================================================== ============================= @@ -83,7 +83,7 @@ Apache ------ The Apache plugin currently `supports -`_ +`_ modern OSes based on Debian, Fedora, SUSE, Gentoo and Darwin. This automates both obtaining *and* installing certificates on an Apache webserver. To specify this plugin on the command line, simply include @@ -275,7 +275,7 @@ haproxy_ Y Y Integration with the HAProxy load balancer s3front_ Y Y Integration with Amazon CloudFront distribution of S3 buckets gandi_ Y N Obtain certificates via the Gandi LiveDNS API varnish_ Y N Obtain certificates via a Varnish server -external_ Y N A plugin for convenient scripting (See also ticket 2782_) +external-auth_ Y Y A plugin for convenient scripting pritunl_ N Y Install certificates in pritunl distributed OpenVPN servers proxmox_ N Y Install certificates in Proxmox Virtualization servers dns-standalone_ Y N Obtain certificates via an integrated DNS server @@ -286,10 +286,9 @@ dns-ispconfig_ Y N DNS Authentication using ISPConfig as DNS server .. _s3front: https://github.com/dlapiduz/letsencrypt-s3front .. _gandi: https://github.com/obynio/certbot-plugin-gandi .. _varnish: http://git.sesse.net/?p=letsencrypt-varnish-plugin -.. _2782: https://github.com/certbot/certbot/issues/2782 .. _pritunl: https://github.com/kharkevich/letsencrypt-pritunl .. _proxmox: https://github.com/kharkevich/letsencrypt-proxmox -.. _external: https://github.com/marcan/letsencrypt-external +.. _external-auth: https://github.com/EnigmaBridge/certbot-external-auth .. _dns-standalone: https://github.com/siilike/certbot-dns-standalone .. _dns-ispconfig: https://github.com/m42e/certbot-dns-ispconfig @@ -680,8 +679,8 @@ Where are my certificates? ========================== All generated keys and issued certificates can be found in -``/etc/letsencrypt/live/$domain``. In the case of creating a SAN certificate -with multiple alternative names, ``$domain`` is the first domain passed in +``/etc/letsencrypt/live/$domain``. In the case of creating a SAN certificate +with multiple alternative names, ``$domain`` is the first domain passed in via -d parameter. Rather than copying, please point your (web) server configuration directly to those files (or create symlinks). During the renewal_, ``/etc/letsencrypt/live`` is updated diff --git a/docs/what.rst b/certbot/docs/what.rst similarity index 100% rename from docs/what.rst rename to certbot/docs/what.rst diff --git a/examples/.gitignore b/certbot/examples/.gitignore similarity index 100% rename from examples/.gitignore rename to certbot/examples/.gitignore diff --git a/examples/cli.ini b/certbot/examples/cli.ini similarity index 100% rename from examples/cli.ini rename to certbot/examples/cli.ini diff --git a/examples/dev-cli.ini b/certbot/examples/dev-cli.ini similarity index 100% rename from examples/dev-cli.ini rename to certbot/examples/dev-cli.ini diff --git a/examples/generate-csr.sh b/certbot/examples/generate-csr.sh similarity index 100% rename from examples/generate-csr.sh rename to certbot/examples/generate-csr.sh diff --git a/examples/openssl.cnf b/certbot/examples/openssl.cnf similarity index 100% rename from examples/openssl.cnf rename to certbot/examples/openssl.cnf diff --git a/examples/plugins/certbot_example_plugins.py b/certbot/examples/plugins/certbot_example_plugins.py similarity index 100% rename from examples/plugins/certbot_example_plugins.py rename to certbot/examples/plugins/certbot_example_plugins.py diff --git a/examples/plugins/setup.py b/certbot/examples/plugins/setup.py similarity index 99% rename from examples/plugins/setup.py rename to certbot/examples/plugins/setup.py index 4538e83b8..ba2b5e4e2 100644 --- a/examples/plugins/setup.py +++ b/certbot/examples/plugins/setup.py @@ -1,6 +1,5 @@ from setuptools import setup - setup( name='certbot-example-plugins', package='certbot_example_plugins.py', diff --git a/local-oldest-requirements.txt b/certbot/local-oldest-requirements.txt similarity index 100% rename from local-oldest-requirements.txt rename to certbot/local-oldest-requirements.txt diff --git a/certbot-nginx/readthedocs.org.requirements.txt b/certbot/readthedocs.org.requirements.txt similarity index 69% rename from certbot-nginx/readthedocs.org.requirements.txt rename to certbot/readthedocs.org.requirements.txt index ca5f33363..f3964e8a7 100644 --- a/certbot-nginx/readthedocs.org.requirements.txt +++ b/certbot/readthedocs.org.requirements.txt @@ -1,12 +1,11 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project # in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# expected and "pip install -e certbot[docs]" must be used instead -e acme --e . --e certbot-nginx[docs] +-e certbot[docs] diff --git a/setup.cfg b/certbot/setup.cfg similarity index 100% rename from setup.cfg rename to certbot/setup.cfg diff --git a/setup.py b/certbot/setup.py similarity index 93% rename from setup.py rename to certbot/setup.py index b230f3ba0..0026ef8e9 100644 --- a/setup.py +++ b/certbot/setup.py @@ -1,10 +1,12 @@ import codecs +from distutils.version import StrictVersion import os import re import sys -from distutils.version import StrictVersion -from setuptools import find_packages, setup, __version__ as setuptools_version +from setuptools import __version__ as setuptools_version +from setuptools import find_packages +from setuptools import setup from setuptools.command.test import test as TestCommand # Workaround for http://bugs.python.org/issue8876, see @@ -59,7 +61,7 @@ install_requires = [ # However environment markers are supported only with setuptools >= 36.2. # So this dependency is not added for old Linux distributions with old setuptools, # in order to allow these systems to build certbot from sources. -pywin32_req = 'pywin32>=225' # do not forget to edit pywin32 dependency accordingly in windows-installer/construct.py +pywin32_req = 'pywin32>=227' # do not forget to edit pywin32 dependency accordingly in windows-installer/construct.py if StrictVersion(setuptools_version) >= StrictVersion('36.2'): install_requires.append(pywin32_req + " ; sys_platform == 'win32'") elif 'bdist_wheel' in sys.argv[1:]: @@ -72,21 +74,21 @@ elif os.name == 'nt': install_requires.append(pywin32_req) dev_extras = [ - 'astroid==1.6.5', 'coverage', 'ipdb', 'pytest', 'pytest-cov', 'pytest-xdist', - 'pylint==1.9.4', 'tox', 'twine', 'wheel', ] dev3_extras = [ + 'astroid', 'mypy', - 'typing', # for python3.4 + 'pylint', + 'typing', # for python3.4 ] docs_extras = [ @@ -157,15 +159,13 @@ setup( 'docs': docs_extras, }, - # to test all packages run "python setup.py test -s - # {acme,certbot_apache,certbot_nginx}" test_suite='certbot', tests_require=["pytest"], cmdclass={"test": PyTest}, entry_points={ 'console_scripts': [ - 'certbot = certbot._internal.main:main', + 'certbot = certbot.main:main', ], 'certbot.plugins': [ 'manual = certbot._internal.plugins.manual:Authenticator', diff --git a/certbot/tests/__init__.py b/certbot/tests/__init__.py deleted file mode 100644 index 2f4d6e07c..000000000 --- a/certbot/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Certbot Tests""" diff --git a/certbot/tests/account_test.py b/certbot/tests/account_test.py index 0f0b47ec4..4a6ed3e01 100644 --- a/certbot/tests/account_test.py +++ b/certbot/tests/account_test.py @@ -8,12 +8,11 @@ import mock import pytz from acme import messages - -import certbot.tests.util as test_util from certbot import errors from certbot.compat import filesystem from certbot.compat import misc from certbot.compat import os +import certbot.tests.util as test_util KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem")) @@ -93,7 +92,6 @@ class AccountMemoryStorageTest(unittest.TestCase): class AccountFileStorageTest(test_util.ConfigTestCase): """Tests for certbot._internal.account.AccountFileStorage.""" - #pylint: disable=too-many-public-methods def setUp(self): super(AccountFileStorageTest, self).setUp() diff --git a/certbot/tests/auth_handler_test.py b/certbot/tests/auth_handler_test.py index 75bd9b45b..7ab3a2baa 100644 --- a/certbot/tests/auth_handler_test.py +++ b/certbot/tests/auth_handler_test.py @@ -8,14 +8,12 @@ import zope.component from acme import challenges from acme import client as acme_client -from acme import messages from acme import errors as acme_errors - +from acme import messages from certbot import achallenges from certbot import errors from certbot import interfaces from certbot import util - from certbot.tests import acme_util from certbot.tests import util as test_util @@ -56,7 +54,7 @@ class ChallengeFactoryTest(unittest.TestCase): errors.Error, self.handler._challenge_factory, authzr, [0]) -class HandleAuthorizationsTest(unittest.TestCase): # pylint: disable=too-many-public-methods +class HandleAuthorizationsTest(unittest.TestCase): """handle_authorizations test. This tests everything except for all functions under _poll_challenges. @@ -496,7 +494,7 @@ class ReportFailedAuthzrsTest(unittest.TestCase): self.authzr1.body.identifier.value = 'example.com' self.authzr1.body.challenges = [http_01, http_01] - kwargs["error"] = messages.Error(typ="dnssec", detail="detail") + kwargs["error"] = messages.Error.with_code("dnssec", detail="detail") http_01_diff = messages.ChallengeBody(**kwargs) self.authzr2 = mock.MagicMock() diff --git a/certbot/tests/cert_manager_test.py b/certbot/tests/cert_manager_test.py index 4cff508e5..81134f02f 100644 --- a/certbot/tests/cert_manager_test.py +++ b/certbot/tests/cert_manager_test.py @@ -9,14 +9,14 @@ import unittest import configobj import mock -from certbot import configuration from certbot import errors -from certbot.compat import os -from certbot.compat import filesystem -from certbot.display import util as display_util +from certbot._internal import configuration from certbot._internal.storage import ALL_FOUR -from certbot.tests import storage_test +from certbot.compat import filesystem +from certbot.compat import os +from certbot.display import util as display_util from certbot.tests import util as test_util +import storage_test class BaseCertManagerTest(test_util.ConfigTestCase): @@ -68,7 +68,6 @@ class UpdateLiveSymlinksTest(BaseCertManagerTest): """ def test_update_live_symlinks(self): """Test update_live_symlinks""" - # pylint: disable=too-many-statements # create files with incorrect symlinks from certbot._internal import cert_manager archive_paths = {} @@ -179,7 +178,7 @@ class CertificatesTest(BaseCertManagerTest): mock_verifier.return_value = None mock_report.return_value = "" self._certificates(self.config) - self.assertFalse(mock_logger.warning.called) #pylint: disable=no-member + self.assertFalse(mock_logger.warning.called) self.assertTrue(mock_report.called) self.assertTrue(mock_utility.called) self.assertTrue(mock_renewable_cert.called) @@ -197,12 +196,12 @@ class CertificatesTest(BaseCertManagerTest): filesystem.makedirs(empty_config.renewal_configs_dir) self._certificates(empty_config) - self.assertFalse(mock_logger.warning.called) #pylint: disable=no-member + self.assertFalse(mock_logger.warning.called) self.assertTrue(mock_utility.called) shutil.rmtree(empty_tempdir) @mock.patch('certbot._internal.cert_manager.ocsp.RevocationChecker.ocsp_revoked') - def test_report_human_readable(self, mock_revoked): #pylint: disable=too-many-statements + def test_report_human_readable(self, mock_revoked): mock_revoked.return_value = None from certbot._internal import cert_manager import datetime @@ -241,7 +240,7 @@ class CertificatesTest(BaseCertManagerTest): # pylint: disable=protected-access out = get_report() self.assertTrue('3 days' in out) - self.assertTrue('VALID' in out and 'INVALID' not in out) + self.assertTrue('VALID' in out and 'INVALID' not in out) cert.is_test_cert = True mock_revoked.return_value = True diff --git a/certbot/tests/cli_test.py b/certbot/tests/cli_test.py index 8a398188c..05da1da4e 100644 --- a/certbot/tests/cli_test.py +++ b/certbot/tests/cli_test.py @@ -1,4 +1,4 @@ -"""Tests for certbot.cli.""" +"""Tests for certbot._internal.cli.""" import argparse import copy import tempfile @@ -9,14 +9,13 @@ import six from six.moves import reload_module # pylint: disable=import-error from acme import challenges - -import certbot.tests.util as test_util -from certbot import cli -from certbot._internal import constants from certbot import errors -from certbot.compat import os -from certbot.compat import filesystem +from certbot._internal import cli +from certbot._internal import constants from certbot._internal.plugins import disco +from certbot.compat import filesystem +from certbot.compat import os +import certbot.tests.util as test_util from certbot.tests.util import TempDirTestCase PLUGINS = disco.PluginsRegistry.find_all() @@ -60,7 +59,7 @@ class FlagDefaultTest(unittest.TestCase): self.assertEqual(cli.flag_default('logs_dir'), 'C:\\Certbot\\log') -class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods +class ParseTest(unittest.TestCase): '''Test the cli args entrypoint''' @@ -94,7 +93,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods return output.getvalue() - @mock.patch("certbot.cli.flag_default") + @mock.patch("certbot._internal.cli.flag_default") def test_cli_ini_domains(self, mock_flag_default): with tempfile.NamedTemporaryFile() as tmp_config: tmp_config.close() # close now because of compatibility issues on Windows @@ -366,7 +365,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods errors.Error, self.parse, "-n --force-interactive".split()) def test_deploy_hook_conflict(self): - with mock.patch("certbot.cli.sys.stderr"): + with mock.patch("certbot._internal.cli.sys.stderr"): self.assertRaises(SystemExit, self.parse, "--renew-hook foo --deploy-hook bar".split()) @@ -386,7 +385,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods self.assertEqual(namespace.renew_hook, value) def test_renew_hook_conflict(self): - with mock.patch("certbot.cli.sys.stderr"): + with mock.patch("certbot._internal.cli.sys.stderr"): self.assertRaises(SystemExit, self.parse, "--deploy-hook foo --renew-hook bar".split()) @@ -406,7 +405,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods self.assertEqual(namespace.renew_hook, value) def test_max_log_backups_error(self): - with mock.patch('certbot.cli.sys.stderr'): + with mock.patch('certbot._internal.cli.sys.stderr'): self.assertRaises( SystemExit, self.parse, "--max-log-backups foo".split()) self.assertRaises( @@ -462,7 +461,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods class DefaultTest(unittest.TestCase): - """Tests for certbot.cli._Default.""" + """Tests for certbot._internal.cli._Default.""" def setUp(self): @@ -536,7 +535,7 @@ class SetByCliTest(unittest.TestCase): def _call_set_by_cli(var, args, verb): - with mock.patch('certbot.cli.helpful_parser') as mock_parser: + with mock.patch('certbot._internal.cli.helpful_parser') as mock_parser: with test_util.patch_get_utility(): mock_parser.args = args mock_parser.verb = verb diff --git a/certbot/tests/client_test.py b/certbot/tests/client_test.py index e7cf84c3c..7232ed84b 100644 --- a/certbot/tests/client_test.py +++ b/certbot/tests/client_test.py @@ -4,16 +4,15 @@ import shutil import tempfile import unittest +from josepy import interfaces import mock -from josepy import interfaces - -import certbot.tests.util as test_util -from certbot._internal import account from certbot import errors -from certbot.compat import os -from certbot.compat import filesystem from certbot import util +from certbot._internal import account +from certbot.compat import filesystem +from certbot.compat import os +import certbot.tests.util as test_util KEY = test_util.load_vector("rsa512_key.pem") CSR_SAN = test_util.load_vector("csr-san_512.pem") @@ -206,7 +205,7 @@ class RegisterTest(test_util.ConfigTestCase): def test_unsupported_error(self): from acme import messages msg = "Test" - mx_err = messages.Error(detail=msg, typ="malformed", title="title") + mx_err = messages.Error.with_code("malformed", detail=msg, title="title") with mock.patch("certbot._internal.client.acme_client.BackwardsCompatibleClientV2") as mock_client: mock_client().client.directory.__getitem__ = mock.Mock( side_effect=self._new_acct_dir_mock @@ -462,9 +461,8 @@ class ClientTest(ClientTestCommon): names = [call[0][0] for call in mock_storage.call_args_list] self.assertEqual(names, ["example_cert", "example.com", "example.com"]) - @mock.patch("certbot.cli.helpful_parser") + @mock.patch("certbot._internal.cli.helpful_parser") def test_save_certificate(self, mock_parser): - # pylint: disable=too-many-locals certs = ["cert_512.pem", "cert-san_512.pem"] tmp_path = tempfile.mkdtemp() filesystem.chmod(tmp_path, 0o755) # TODO: really?? diff --git a/certbot/tests/compat/filesystem_test.py b/certbot/tests/compat/filesystem_test.py index 7a8b89974..e721bbd48 100644 --- a/certbot/tests/compat/filesystem_test.py +++ b/certbot/tests/compat/filesystem_test.py @@ -5,6 +5,13 @@ import unittest import mock +from certbot import util +from certbot._internal import lock +from certbot.compat import filesystem +from certbot.compat import os +import certbot.tests.util as test_util +from certbot.tests.util import TempDirTestCase + try: # pylint: disable=import-error import win32api @@ -15,12 +22,6 @@ try: except ImportError: POSIX_MODE = True -import certbot.tests.util as test_util -from certbot._internal import lock -from certbot import util -from certbot.compat import os -from certbot.compat import filesystem -from certbot.tests.util import TempDirTestCase EVERYBODY_SID = 'S-1-1-0' @@ -362,6 +363,8 @@ class CheckPermissionsTest(test_util.TempDirTestCase): self.assertTrue(filesystem.check_owner(self.probe_path)) import os as std_os # pylint: disable=os-module-forbidden + # See related inline comment in certbot.compat.filesystem.check_owner method + # that explains why MyPy/PyLint check disable is needed here. uid = std_os.getuid() with mock.patch('os.getuid') as mock_uid: diff --git a/certbot/tests/configuration_test.py b/certbot/tests/configuration_test.py index e1e090fb5..d748b9bfb 100644 --- a/certbot/tests/configuration_test.py +++ b/certbot/tests/configuration_test.py @@ -1,28 +1,28 @@ -"""Tests for certbot.configuration.""" +"""Tests for certbot._internal.configuration.""" import unittest import mock -from certbot._internal import constants from certbot import errors +from certbot._internal import constants from certbot.compat import misc from certbot.compat import os from certbot.tests import util as test_util class NamespaceConfigTest(test_util.ConfigTestCase): - """Tests for certbot.configuration.NamespaceConfig.""" + """Tests for certbot._internal.configuration.NamespaceConfig.""" def setUp(self): super(NamespaceConfigTest, self).setUp() - self.config.foo = 'bar' + self.config.foo = 'bar' # pylint: disable=blacklisted-name self.config.server = 'https://acme-server.org:443/new' self.config.https_port = 1234 self.config.http01_port = 4321 def test_init_same_ports(self): self.config.namespace.https_port = 4321 - from certbot.configuration import NamespaceConfig + from certbot._internal.configuration import NamespaceConfig self.assertRaises(errors.Error, NamespaceConfig, self.config.namespace) def test_proxy_getattr(self): @@ -38,7 +38,7 @@ class NamespaceConfigTest(test_util.ConfigTestCase): self.assertEqual(['user:pass@acme.server:443', 'p', 'a', 't', 'h'], self.config.server_path.split(os.path.sep)) - @mock.patch('certbot.configuration.constants') + @mock.patch('certbot._internal.configuration.constants') def test_dynamic_dirs(self, mock_constants): mock_constants.ACCOUNTS_DIR = 'acc' mock_constants.BACKUP_DIR = 'backups' @@ -70,7 +70,7 @@ class NamespaceConfigTest(test_util.ConfigTestCase): os.path.normpath(os.path.join(self.config.work_dir, 't'))) def test_absolute_paths(self): - from certbot.configuration import NamespaceConfig + from certbot._internal.configuration import NamespaceConfig config_base = "foo" work_base = "bar" @@ -103,7 +103,7 @@ class NamespaceConfigTest(test_util.ConfigTestCase): self.assertTrue(os.path.isabs(config.key_dir)) self.assertTrue(os.path.isabs(config.temp_checkpoint_dir)) - @mock.patch('certbot.configuration.constants') + @mock.patch('certbot._internal.configuration.constants') def test_renewal_dynamic_dirs(self, mock_constants): mock_constants.ARCHIVE_DIR = 'a' mock_constants.LIVE_DIR = 'l' @@ -118,7 +118,7 @@ class NamespaceConfigTest(test_util.ConfigTestCase): self.config.config_dir, 'renewal_configs')) def test_renewal_absolute_paths(self): - from certbot.configuration import NamespaceConfig + from certbot._internal.configuration import NamespaceConfig config_base = "foo" work_base = "bar" diff --git a/certbot/tests/crypto_util_test.py b/certbot/tests/crypto_util_test.py index 2673f4219..1d642ae9e 100644 --- a/certbot/tests/crypto_util_test.py +++ b/certbot/tests/crypto_util_test.py @@ -2,16 +2,16 @@ import logging import unittest -import OpenSSL import mock +import OpenSSL import zope.component -import certbot.tests.util as test_util from certbot import errors from certbot import interfaces from certbot import util -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os +import certbot.tests.util as test_util RSA256_KEY = test_util.load_vector('rsa256_key.pem') RSA256_KEY_PATH = test_util.vector_path('rsa256_key.pem') @@ -164,7 +164,7 @@ class ImportCSRFileTest(unittest.TestCase): test_util.load_vector('cert_512.pem')) -class MakeKeyTest(unittest.TestCase): # pylint: disable=too-few-public-methods +class MakeKeyTest(unittest.TestCase): """Tests for certbot.crypto_util.make_key.""" def test_it(self): # pylint: disable=no-self-use @@ -181,15 +181,15 @@ class VerifyCertSetup(unittest.TestCase): super(VerifyCertSetup, self).setUp() self.renewable_cert = mock.MagicMock() - self.renewable_cert.cert = SS_CERT_PATH - self.renewable_cert.chain = SS_CERT_PATH - self.renewable_cert.privkey = RSA2048_KEY_PATH - self.renewable_cert.fullchain = test_util.vector_path('cert_fullchain_2048.pem') + self.renewable_cert.cert_path = SS_CERT_PATH + self.renewable_cert.chain_path = SS_CERT_PATH + self.renewable_cert.key_path = RSA2048_KEY_PATH + self.renewable_cert.fullchain_path = test_util.vector_path('cert_fullchain_2048.pem') self.bad_renewable_cert = mock.MagicMock() - self.bad_renewable_cert.chain = SS_CERT_PATH - self.bad_renewable_cert.cert = SS_CERT_PATH - self.bad_renewable_cert.fullchain = SS_CERT_PATH + self.bad_renewable_cert.chain_path = SS_CERT_PATH + self.bad_renewable_cert.cert_path = SS_CERT_PATH + self.bad_renewable_cert.fullchain_path = SS_CERT_PATH class VerifyRenewableCertTest(VerifyCertSetup): @@ -219,13 +219,13 @@ class VerifyRenewableCertSigTest(VerifyCertSetup): def test_cert_sig_match_ec(self): renewable_cert = mock.MagicMock() - renewable_cert.cert = P256_CERT_PATH - renewable_cert.chain = P256_CERT_PATH - renewable_cert.privkey = P256_KEY + renewable_cert.cert_path = P256_CERT_PATH + renewable_cert.chain_path = P256_CERT_PATH + renewable_cert.key_path = P256_KEY self.assertEqual(None, self._call(renewable_cert)) def test_cert_sig_mismatch(self): - self.bad_renewable_cert.cert = test_util.vector_path('cert_512_bad.pem') + self.bad_renewable_cert.cert_path = test_util.vector_path('cert_512_bad.pem') self.assertRaises(errors.Error, self._call, self.bad_renewable_cert) diff --git a/certbot/tests/display/completer_test.py b/certbot/tests/display/completer_test.py index 262e0b344..5ddf69266 100644 --- a/certbot/tests/display/completer_test.py +++ b/certbot/tests/display/completer_test.py @@ -10,10 +10,9 @@ import unittest import mock from six.moves import reload_module # pylint: disable=import-error -from acme.magic_typing import List # pylint: disable=unused-import,no-name-in-module - -from certbot.compat import os # pylint: disable=ungrouped-imports +from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module from certbot.compat import filesystem # pylint: disable=ungrouped-imports +from certbot.compat import os # pylint: disable=ungrouped-imports import certbot.tests.util as test_util # pylint: disable=ungrouped-imports diff --git a/certbot/tests/display/ops_test.py b/certbot/tests/display/ops_test.py index 26d4eade2..5df7bfcf8 100644 --- a/certbot/tests/display/ops_test.py +++ b/certbot/tests/display/ops_test.py @@ -8,14 +8,13 @@ import mock import zope.component from acme import messages - -import certbot.tests.util as test_util -from certbot._internal import account from certbot import errors -from certbot.compat import os +from certbot._internal import account from certbot.compat import filesystem +from certbot.compat import os from certbot.display import ops from certbot.display import util as display_util +import certbot.tests.util as test_util KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem")) @@ -354,7 +353,6 @@ class ChooseNamesTest(unittest.TestCase): class SuccessInstallationTest(unittest.TestCase): - # pylint: disable=too-few-public-methods """Test the success installation message.""" @classmethod def _call(cls, names): @@ -376,7 +374,6 @@ class SuccessInstallationTest(unittest.TestCase): class SuccessRenewalTest(unittest.TestCase): - # pylint: disable=too-few-public-methods """Test the success renewal message.""" @classmethod def _call(cls, names): @@ -397,7 +394,6 @@ class SuccessRenewalTest(unittest.TestCase): self.assertTrue(name in arg) class SuccessRevocationTest(unittest.TestCase): - # pylint: disable=too-few-public-methods """Test the success revocation message.""" @classmethod def _call(cls, path): diff --git a/certbot/tests/display/util_test.py b/certbot/tests/display/util_test.py index 138bfe628..615f33406 100644 --- a/certbot/tests/display/util_test.py +++ b/certbot/tests/display/util_test.py @@ -58,7 +58,6 @@ class FileOutputDisplayTest(unittest.TestCase): functions look to a user, uncomment the test_visual function. """ - # pylint:disable=too-many-public-methods def setUp(self): super(FileOutputDisplayTest, self).setUp() self.mock_stdout = mock.MagicMock() @@ -312,12 +311,12 @@ class FileOutputDisplayTest(unittest.TestCase): def test_methods_take_force_interactive(self): # Every IDisplay method implemented by FileDisplay must take # force_interactive to prevent workflow regressions. - for name in interfaces.IDisplay.names(): # pylint: disable=no-member,no-value-for-parameter + for name in interfaces.IDisplay.names(): if six.PY2: - getargspec = inspect.getargspec # pylint: disable=no-member + getargspec = inspect.getargspec else: - getargspec = inspect.getfullargspec # pylint: disable=no-member - arg_spec = getargspec(getattr(self.displayer, name)) + getargspec = inspect.getfullargspec + arg_spec = getargspec(getattr(self.displayer, name)) # pylint: disable=deprecated-method self.assertTrue("force_interactive" in arg_spec.args) @@ -373,14 +372,14 @@ class NoninteractiveDisplayTest(unittest.TestCase): # NoninteractiveDisplay. # Use pylint code for disable to keep on single line under line length limit - for name in interfaces.IDisplay.names(): # pylint: disable=no-member,E1120 + for name in interfaces.IDisplay.names(): # pylint: disable=E1120 method = getattr(self.displayer, name) # asserts method accepts arbitrary keyword arguments if six.PY2: - result = inspect.getargspec(method).keywords # pylint: disable=no-member + result = inspect.getargspec(method).keywords # pylint:deprecated-method self.assertFalse(result is None) else: - result = inspect.getfullargspec(method).varkw # pylint: disable=no-member + result = inspect.getfullargspec(method).varkw self.assertFalse(result is None) diff --git a/certbot/tests/eff_test.py b/certbot/tests/eff_test.py index b53187f47..cdd7908a3 100644 --- a/certbot/tests/eff_test.py +++ b/certbot/tests/eff_test.py @@ -111,7 +111,7 @@ class SubscribeTest(unittest.TestCase): @test_util.patch_get_utility() def test_bad_status(self, mock_get_utility): self.json['status'] = False - self._call() # pylint: disable=no-value-for-parameter + self._call() actual = self._get_reported_message(mock_get_utility) expected_part = 'because your e-mail address appears to be invalid.' self.assertTrue(expected_part in actual) @@ -120,7 +120,7 @@ class SubscribeTest(unittest.TestCase): def test_not_ok(self, mock_get_utility): self.response.ok = False self.response.raise_for_status.side_effect = requests.exceptions.HTTPError - self._call() # pylint: disable=no-value-for-parameter + self._call() actual = self._get_reported_message(mock_get_utility) unexpected_part = 'because' self.assertFalse(unexpected_part in actual) @@ -128,7 +128,7 @@ class SubscribeTest(unittest.TestCase): @test_util.patch_get_utility() def test_response_not_json(self, mock_get_utility): self.response.json.side_effect = ValueError() - self._call() # pylint: disable=no-value-for-parameter + self._call() actual = self._get_reported_message(mock_get_utility) expected_part = 'problem' self.assertTrue(expected_part in actual) @@ -136,7 +136,7 @@ class SubscribeTest(unittest.TestCase): @test_util.patch_get_utility() def test_response_json_missing_status_element(self, mock_get_utility): self.json.clear() - self._call() # pylint: disable=no-value-for-parameter + self._call() actual = self._get_reported_message(mock_get_utility) expected_part = 'problem' self.assertTrue(expected_part in actual) @@ -147,7 +147,7 @@ class SubscribeTest(unittest.TestCase): @test_util.patch_get_utility() def test_subscribe(self, mock_get_utility): - self._call() # pylint: disable=no-value-for-parameter + self._call() self.assertFalse(mock_get_utility.called) diff --git a/certbot/tests/error_handler_test.py b/certbot/tests/error_handler_test.py index 3803b70e3..45fec7f39 100644 --- a/certbot/tests/error_handler_test.py +++ b/certbot/tests/error_handler_test.py @@ -6,10 +6,9 @@ import unittest import mock -# pylint: disable=unused-import, no-name-in-module -from acme.magic_typing import Callable, Dict, Union -# pylint: enable=unused-import, no-name-in-module - +from acme.magic_typing import Callable # 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 Union # pylint: disable=unused-import, no-name-in-module from certbot.compat import os diff --git a/certbot/tests/errors_test.py b/certbot/tests/errors_test.py index c8a6c4ac5..d6c829322 100644 --- a/certbot/tests/errors_test.py +++ b/certbot/tests/errors_test.py @@ -4,7 +4,6 @@ import unittest import mock from acme import messages - from certbot import achallenges from certbot.tests import acme_util @@ -14,25 +13,27 @@ class FailedChallengesTest(unittest.TestCase): def setUp(self): from certbot.errors import FailedChallenges - self.error = FailedChallenges(set([achallenges.DNS( + self.error = FailedChallenges({achallenges.DNS( domain="example.com", challb=messages.ChallengeBody( chall=acme_util.DNS01, uri=None, - error=messages.Error(typ="tls", detail="detail")))])) + error=messages.Error.with_code("tls", detail="detail")))}) def test_str(self): self.assertTrue(str(self.error).startswith( - "Failed authorization procedure. example.com (dns-01): tls")) + "Failed authorization procedure. example.com (dns-01): " + "urn:ietf:params:acme:error:tls")) def test_unicode(self): from certbot.errors import FailedChallenges arabic_detail = u'\u0639\u062f\u0627\u0644\u0629' - arabic_error = FailedChallenges(set([achallenges.DNS( + arabic_error = FailedChallenges({achallenges.DNS( domain="example.com", challb=messages.ChallengeBody( chall=acme_util.DNS01, uri=None, - error=messages.Error(typ="tls", detail=arabic_detail)))])) + error=messages.Error.with_code("tls", detail=arabic_detail)))}) self.assertTrue(str(arabic_error).startswith( - "Failed authorization procedure. example.com (dns-01): tls")) + "Failed authorization procedure. example.com (dns-01): " + "urn:ietf:params:acme:error:tls")) class StandaloneBindErrorTest(unittest.TestCase): diff --git a/certbot/tests/hook_test.py b/certbot/tests/hook_test.py index 017edc560..a3bba57d2 100644 --- a/certbot/tests/hook_test.py +++ b/certbot/tests/hook_test.py @@ -1,25 +1,25 @@ -"""Tests for certbot.hooks.""" +"""Tests for certbot._internal.hooks.""" import unittest import mock -from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module from certbot import errors from certbot import util -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os from certbot.tests import util as test_util class ValidateHooksTest(unittest.TestCase): - """Tests for certbot.hooks.validate_hooks.""" + """Tests for certbot._internal.hooks.validate_hooks.""" @classmethod def _call(cls, *args, **kwargs): - from certbot.hooks import validate_hooks + from certbot._internal.hooks import validate_hooks return validate_hooks(*args, **kwargs) - @mock.patch("certbot.hooks.validate_hook") + @mock.patch("certbot._internal.hooks.validate_hook") def test_it(self, mock_validate_hook): config = mock.MagicMock() self._call(config) @@ -31,30 +31,30 @@ class ValidateHooksTest(unittest.TestCase): class ValidateHookTest(test_util.TempDirTestCase): - """Tests for certbot.hooks.validate_hook.""" + """Tests for certbot._internal.hooks.validate_hook.""" @classmethod def _call(cls, *args, **kwargs): - from certbot.hooks import validate_hook + from certbot._internal.hooks import validate_hook return validate_hook(*args, **kwargs) def test_hook_not_executable(self): # prevent unnecessary modifications to PATH - with mock.patch("certbot.hooks.plug_util.path_surgery"): + with mock.patch("certbot._internal.hooks.plug_util.path_surgery"): # We just mock out filesystem.is_executable since on Windows, it is difficult # to get a fully working test around executable permissions. See # certbot.tests.compat.filesystem::NotExecutableTest for more in-depth tests. - with mock.patch("certbot.hooks.filesystem.is_executable", return_value=False): + with mock.patch("certbot._internal.hooks.filesystem.is_executable", return_value=False): self.assertRaises(errors.HookCommandNotFound, self._call, 'dummy', "foo") - @mock.patch("certbot.hooks.util.exe_exists") + @mock.patch("certbot._internal.hooks.util.exe_exists") def test_not_found(self, mock_exe_exists): mock_exe_exists.return_value = False - with mock.patch("certbot.hooks.plug_util.path_surgery") as mock_ps: + with mock.patch("certbot._internal.hooks.plug_util.path_surgery") as mock_ps: self.assertRaises(errors.HookCommandNotFound, self._call, "foo", "bar") self.assertTrue(mock_ps.called) - @mock.patch("certbot.hooks._prog") + @mock.patch("certbot._internal.hooks._prog") def test_unset(self, mock_prog): self._call(None, "foo") self.assertFalse(mock_prog.called) @@ -70,24 +70,24 @@ class HookTest(test_util.ConfigTestCase): @classmethod def _call_with_mock_execute(cls, *args, **kwargs): - """Calls self._call after mocking out certbot.hooks.execute. + """Calls self._call after mocking out certbot._internal.hooks.execute. The mock execute object is returned rather than the return value of self._call. """ - with mock.patch("certbot.hooks.execute") as mock_execute: + with mock.patch("certbot._internal.hooks.execute") as mock_execute: mock_execute.return_value = ("", "") cls._call(*args, **kwargs) return mock_execute class PreHookTest(HookTest): - """Tests for certbot.hooks.pre_hook.""" + """Tests for certbot._internal.hooks.pre_hook.""" @classmethod def _call(cls, *args, **kwargs): - from certbot.hooks import pre_hook + from certbot._internal.hooks import pre_hook return pre_hook(*args, **kwargs) def setUp(self): @@ -107,7 +107,7 @@ class PreHookTest(HookTest): super(PreHookTest, self).tearDown() def _reset_pre_hook_already(self): - from certbot.hooks import executed_pre_hooks + from certbot._internal.hooks import executed_pre_hooks executed_pre_hooks.clear() def test_certonly(self): @@ -128,7 +128,7 @@ class PreHookTest(HookTest): self.config.verb = "renew" os.remove(self.dir_hook) - with mock.patch("certbot.hooks.logger") as mock_logger: + with mock.patch("certbot._internal.hooks.logger") as mock_logger: mock_execute = self._call_with_mock_execute(self.config) self.assertFalse(mock_execute.called) self.assertFalse(mock_logger.info.called) @@ -154,18 +154,18 @@ class PreHookTest(HookTest): self._test_no_executions_common() def _test_no_executions_common(self): - with mock.patch("certbot.hooks.logger") as mock_logger: + with mock.patch("certbot._internal.hooks.logger") as mock_logger: mock_execute = self._call_with_mock_execute(self.config) self.assertFalse(mock_execute.called) self.assertTrue(mock_logger.info.called) class PostHookTest(HookTest): - """Tests for certbot.hooks.post_hook.""" + """Tests for certbot._internal.hooks.post_hook.""" @classmethod def _call(cls, *args, **kwargs): - from certbot.hooks import post_hook + from certbot._internal.hooks import post_hook return post_hook(*args, **kwargs) def setUp(self): @@ -185,7 +185,7 @@ class PostHookTest(HookTest): super(PostHookTest, self).tearDown() def _reset_post_hook_eventually(self): - from certbot.hooks import post_hooks + from certbot._internal.hooks import post_hooks del post_hooks[:] def test_certonly_and_run_with_hook(self): @@ -239,27 +239,27 @@ class PostHookTest(HookTest): self.assertEqual(self._get_eventually(), expected) def _get_eventually(self): - from certbot.hooks import post_hooks + from certbot._internal.hooks import post_hooks return post_hooks class RunSavedPostHooksTest(HookTest): - """Tests for certbot.hooks.run_saved_post_hooks.""" + """Tests for certbot._internal.hooks.run_saved_post_hooks.""" @classmethod def _call(cls, *args, **kwargs): - from certbot.hooks import run_saved_post_hooks + from certbot._internal.hooks import run_saved_post_hooks return run_saved_post_hooks() def _call_with_mock_execute_and_eventually(self, *args, **kwargs): """Call run_saved_post_hooks but mock out execute and eventually - certbot.hooks.post_hooks is replaced with + certbot._internal.hooks.post_hooks is replaced with self.eventually. The mock execute object is returned rather than the return value of run_saved_post_hooks. """ - eventually_path = "certbot.hooks.post_hooks" + eventually_path = "certbot._internal.hooks.post_hooks" with mock.patch(eventually_path, new=self.eventually): return self._call_with_mock_execute(*args, **kwargs) @@ -290,7 +290,7 @@ class RenewalHookTest(HookTest): # pylint: disable=abstract-method def _call_with_mock_execute(self, *args, **kwargs): - """Calls self._call after mocking out certbot.hooks.execute. + """Calls self._call after mocking out certbot._internal.hooks.execute. The mock execute object is returned rather than the return value of self._call. The mock execute object asserts that environment @@ -311,7 +311,7 @@ class RenewalHookTest(HookTest): self.assertEqual(os.environ["RENEWED_LINEAGE"], lineage) return ("", "") - with mock.patch("certbot.hooks.execute") as mock_execute: + with mock.patch("certbot._internal.hooks.execute") as mock_execute: mock_execute.side_effect = execute_side_effect self._call(*args, **kwargs) return mock_execute @@ -329,14 +329,14 @@ class RenewalHookTest(HookTest): class DeployHookTest(RenewalHookTest): - """Tests for certbot.hooks.deploy_hook.""" + """Tests for certbot._internal.hooks.deploy_hook.""" @classmethod def _call(cls, *args, **kwargs): - from certbot.hooks import deploy_hook + from certbot._internal.hooks import deploy_hook return deploy_hook(*args, **kwargs) - @mock.patch("certbot.hooks.logger") + @mock.patch("certbot._internal.hooks.logger") def test_dry_run(self, mock_logger): self.config.deploy_hook = "foo" self.config.dry_run = True @@ -345,7 +345,7 @@ class DeployHookTest(RenewalHookTest): self.assertFalse(mock_execute.called) self.assertTrue(mock_logger.warning.called) - @mock.patch("certbot.hooks.logger") + @mock.patch("certbot._internal.hooks.logger") def test_no_hook(self, mock_logger): self.config.deploy_hook = None mock_execute = self._call_with_mock_execute( @@ -363,11 +363,11 @@ class DeployHookTest(RenewalHookTest): class RenewHookTest(RenewalHookTest): - """Tests for certbot.hooks.renew_hook""" + """Tests for certbot._internal.hooks.renew_hook""" @classmethod def _call(cls, *args, **kwargs): - from certbot.hooks import renew_hook + from certbot._internal.hooks import renew_hook return renew_hook(*args, **kwargs) def setUp(self): @@ -385,7 +385,7 @@ class RenewHookTest(RenewalHookTest): self.config, ["example.org"], "/foo/bar") mock_execute.assert_called_once_with("deploy-hook", self.config.renew_hook) - @mock.patch("certbot.hooks.logger") + @mock.patch("certbot._internal.hooks.logger") def test_dry_run(self, mock_logger): self.config.dry_run = True mock_execute = self._call_with_mock_execute( @@ -397,7 +397,7 @@ class RenewHookTest(RenewalHookTest): self.config.renew_hook = None os.remove(self.dir_hook) - with mock.patch("certbot.hooks.logger") as mock_logger: + with mock.patch("certbot._internal.hooks.logger") as mock_logger: mock_execute = self._call_with_mock_execute( self.config, ["example.org"], "/foo/bar") self.assertFalse(mock_execute.called) @@ -417,11 +417,11 @@ class RenewHookTest(RenewalHookTest): class ExecuteTest(unittest.TestCase): - """Tests for certbot.hooks.execute.""" + """Tests for certbot._internal.hooks.execute.""" @classmethod def _call(cls, *args, **kwargs): - from certbot.hooks import execute + from certbot._internal.hooks import execute return execute(*args, **kwargs) def test_it(self): @@ -433,10 +433,10 @@ class ExecuteTest(unittest.TestCase): def _test_common(self, returncode, stdout, stderr): given_command = "foo" given_name = "foo-hook" - with mock.patch("certbot.hooks.Popen") as mock_popen: + with mock.patch("certbot._internal.hooks.Popen") as mock_popen: mock_popen.return_value.communicate.return_value = (stdout, stderr) mock_popen.return_value.returncode = returncode - with mock.patch("certbot.hooks.logger") as mock_logger: + with mock.patch("certbot._internal.hooks.logger") as mock_logger: self.assertEqual(self._call(given_name, given_command), (stderr, stdout)) executed_command = mock_popen.call_args[1].get( @@ -453,11 +453,11 @@ class ExecuteTest(unittest.TestCase): class ListHooksTest(test_util.TempDirTestCase): - """Tests for certbot.hooks.list_hooks.""" + """Tests for certbot._internal.hooks.list_hooks.""" @classmethod def _call(cls, *args, **kwargs): - from certbot.hooks import list_hooks + from certbot._internal.hooks import list_hooks return list_hooks(*args, **kwargs) def test_empty(self): diff --git a/certbot/tests/lock_test.py b/certbot/tests/lock_test.py index dae643269..5a48009fd 100644 --- a/certbot/tests/lock_test.py +++ b/certbot/tests/lock_test.py @@ -2,6 +2,13 @@ import functools import multiprocessing import unittest + +import mock + +from certbot import errors +from certbot.compat import os +from certbot.tests import util as test_util + try: import fcntl # pylint: disable=import-error,unused-import except ImportError: @@ -9,11 +16,7 @@ except ImportError: else: POSIX_MODE = True -import mock -from certbot import errors -from certbot.compat import os -from certbot.tests import util as test_util class LockDirTest(test_util.TempDirTestCase): diff --git a/certbot/tests/log_test.py b/certbot/tests/log_test.py index 36c473bd2..3b9adbbf2 100644 --- a/certbot/tests/log_test.py +++ b/certbot/tests/log_test.py @@ -10,10 +10,9 @@ import six from acme import messages from acme.magic_typing import Optional # pylint: disable=unused-import, no-name-in-module - -from certbot._internal import constants from certbot import errors from certbot import util +from certbot._internal import constants from certbot.compat import filesystem from certbot.compat import os from certbot.tests import util as test_util diff --git a/certbot/tests/main_test.py b/certbot/tests/main_test.py index 835951b70..7b22c81d6 100644 --- a/certbot/tests/main_test.py +++ b/certbot/tests/main_test.py @@ -19,24 +19,23 @@ import six from six.moves import reload_module # pylint: disable=import-error from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - -import certbot.tests.util as test_util -from certbot._internal import account -from certbot import cli -from certbot import configuration -from certbot._internal import constants from certbot import crypto_util from certbot import errors from certbot import interfaces # pylint: disable=unused-import +from certbot import util +from certbot._internal import account +from certbot._internal import cli +from certbot._internal import configuration +from certbot._internal import constants from certbot._internal import main from certbot._internal import updater -from certbot import util -from certbot.compat import os -from certbot.compat import filesystem from certbot._internal.plugins import disco -from certbot.plugins import enhancements from certbot._internal.plugins import manual from certbot._internal.plugins import null +from certbot.compat import filesystem +from certbot.compat import os +from certbot.plugins import enhancements +import certbot.tests.util as test_util CERT_PATH = test_util.vector_path('cert_512.pem') CERT = test_util.vector_path('cert_512.pem') @@ -356,7 +355,6 @@ class DeleteIfAppropriateTest(test_util.ConfigTestCase): util_mock.yesno.return_value = False self._test_delete_opt_out_common(mock_get_utility) - # pylint: disable=too-many-arguments @mock.patch('certbot._internal.storage.renewal_file_for_certname') @mock.patch('certbot._internal.cert_manager.delete') @mock.patch('certbot._internal.cert_manager.match_and_check_overlaps') @@ -376,7 +374,6 @@ class DeleteIfAppropriateTest(test_util.ConfigTestCase): self._call(config) mock_delete.assert_not_called() - # pylint: disable=too-many-arguments @mock.patch('certbot._internal.storage.renewal_file_for_certname') @mock.patch('certbot._internal.cert_manager.match_and_check_overlaps') @mock.patch('certbot._internal.storage.full_archive_path') @@ -395,7 +392,6 @@ class DeleteIfAppropriateTest(test_util.ConfigTestCase): self._call(config) self.assertEqual(mock_delete.call_count, 1) - # pylint: disable=too-many-arguments @mock.patch('certbot._internal.storage.renewal_file_for_certname') @mock.patch('certbot._internal.cert_manager.match_and_check_overlaps') @mock.patch('certbot._internal.storage.full_archive_path') @@ -416,7 +412,6 @@ class DeleteIfAppropriateTest(test_util.ConfigTestCase): self._call(config) self.assertEqual(mock_delete.call_count, 1) - # pylint: disable=too-many-arguments @mock.patch('certbot._internal.storage.renewal_file_for_certname') @mock.patch('certbot._internal.cert_manager.match_and_check_overlaps') @mock.patch('certbot._internal.storage.full_archive_path') @@ -507,7 +502,7 @@ class DetermineAccountTest(test_util.ConfigTestCase): self.assertEqual('other email', self.config.email) -class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-methods +class MainTest(test_util.ConfigTestCase): """Tests for different commands.""" def setUp(self): @@ -715,7 +710,7 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met # This needed two calls to find_all(), which we're avoiding for now # because of possible side effects: # https://github.com/letsencrypt/letsencrypt/commit/51ed2b681f87b1eb29088dd48718a54f401e4855 - #with mock.patch('certbot.cli.plugins_testable') as plugins: + #with mock.patch('certbot._internal.cli.plugins_testable') as plugins: # plugins.return_value = {"apache": True, "nginx": True} # ret, _, _, _ = self._call(args) # self.assertTrue("Too many flags setting" in ret) @@ -970,7 +965,6 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met args=None, should_renew=True, error_expected=False, quiet_mode=False, expiry_date=datetime.datetime.now(), reuse_key=False): - # pylint: disable=too-many-locals,too-many-arguments,too-many-branches cert_path = test_util.vector_path('cert_512.pem') chain_path = os.path.normpath(os.path.join(self.config.config_dir, 'live/foo.bar/fullchain.pem')) @@ -1145,7 +1139,7 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met test_util.make_lineage(self.config.config_dir, 'sample-renewal.conf') args = ["renew", "--dry-run", "--post-hook=no-such-command", "--disable-hook-validation"] - with mock.patch("certbot.hooks.post_hook"): + with mock.patch("certbot._internal.hooks.post_hook"): self._test_renewal_common(True, [], args=args, should_renew=True, error_expected=False) @@ -1400,33 +1394,6 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met "user@example.org"]) self.assertTrue("Could not find an existing account" in x[0]) - # TODO: When `certbot register --update-registration` is fully deprecated, - # delete the following test - def test_update_registration_no_existing_accounts_deprecated(self): - # with mock.patch('certbot._internal.main.client') as mocked_client: - with mock.patch('certbot._internal.main.account') as mocked_account: - mocked_storage = mock.MagicMock() - mocked_account.AccountFileStorage.return_value = mocked_storage - mocked_storage.find_all.return_value = [] - x = self._call_no_clientmock( - ["register", "--update-registration", "--email", - "user@example.org"]) - self.assertTrue("Could not find an existing account" in x[0]) - - # TODO: When `certbot register --update-registration` is fully deprecated, - # delete the following test - def test_update_registration_unsafely_deprecated(self): - # This test will become obsolete when register --update-registration - # supports removing an e-mail address from the account - with mock.patch('certbot._internal.main.account') as mocked_account: - mocked_storage = mock.MagicMock() - mocked_account.AccountFileStorage.return_value = mocked_storage - mocked_storage.find_all.return_value = ["an account"] - x = self._call_no_clientmock( - "register --update-registration " - "--register-unsafely-without-email".split()) - self.assertTrue("--register-unsafely-without-email" in x[0]) - @mock.patch('certbot._internal.main.display_ops.get_email') @test_util.patch_get_utility() def test_update_account_with_email(self, mock_utility, mock_email): @@ -1457,42 +1424,6 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met email in mock_utility().add_message.call_args[0][0]) self.assertTrue(mock_handle.called) - # TODO: When `certbot register --update-registration` is fully deprecated, - # delete the following test - @mock.patch('certbot._internal.main.display_ops.get_email') - @test_util.patch_get_utility() - def test_update_registration_with_email_deprecated(self, mock_utility, mock_email): - email = "user@example.com" - mock_email.return_value = email - with mock.patch('certbot._internal.eff.handle_subscription') as mock_handle: - with mock.patch('certbot._internal.main._determine_account') as mocked_det: - with mock.patch('certbot._internal.main.account') as mocked_account: - with mock.patch('certbot._internal.main.client') as mocked_client: - mocked_storage = mock.MagicMock() - mocked_account.AccountFileStorage.return_value = mocked_storage - mocked_storage.find_all.return_value = ["an account"] - mock_acc = mock.MagicMock() - mock_regr = mock_acc.regr - mocked_det.return_value = (mock_acc, "foo") - cb_client = mock.MagicMock() - mocked_client.Client.return_value = cb_client - x = self._call_no_clientmock( - ["register", "--update-registration"]) - # When registration change succeeds, the return value - # of register() is None - self.assertTrue(x[0] is None) - # and we got supposedly did update the registration from - # the server - reg_arg = cb_client.acme.update_registration.call_args[0][0] - # Test the return value of .update() was used because - # the regr is immutable. - self.assertEqual(reg_arg, mock_regr.update()) - # and we saved the updated registration on disk - self.assertTrue(mocked_storage.save_regr.called) - self.assertTrue( - email in mock_utility().add_message.call_args[0][0]) - self.assertTrue(mock_handle.called) - @mock.patch('certbot._internal.plugins.selection.choose_configurator_plugins') @mock.patch('certbot._internal.updater._run_updaters') def test_plugin_selection_error(self, mock_run, mock_choose): diff --git a/certbot/tests/ocsp_test.py b/certbot/tests/ocsp_test.py index 500d5960b..6e4ab52b8 100644 --- a/certbot/tests/ocsp_test.py +++ b/certbot/tests/ocsp_test.py @@ -1,13 +1,21 @@ """Tests for ocsp.py""" # pylint: disable=protected-access import contextlib +from datetime import datetime +from datetime import timedelta import unittest -from datetime import datetime, timedelta +from cryptography import x509 +from cryptography.exceptions import InvalidSignature +from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes # type: ignore -from cryptography.exceptions import UnsupportedAlgorithm, InvalidSignature -from cryptography import x509 +import mock +import pytz + +from certbot import errors +from certbot.tests import util as test_util + try: # Only cryptography>=2.5 has ocsp module # and signature_hash_algorithm attribute in OCSPResponse class @@ -15,11 +23,7 @@ try: getattr(ocsp_lib.OCSPResponse, 'signature_hash_algorithm') except (ImportError, AttributeError): # pragma: no cover ocsp_lib = None # type: ignore -import mock -import pytz -from certbot import errors -from certbot.tests import util as test_util out = """Missing = in header key=value ocsp: Use -help for summary. diff --git a/certbot/tests/plugins/__init__.py b/certbot/tests/plugins/__init__.py new file mode 100644 index 000000000..3cfcb5008 --- /dev/null +++ b/certbot/tests/plugins/__init__.py @@ -0,0 +1 @@ +"""Certbot Plugins Tests""" diff --git a/certbot/plugins/common_test.py b/certbot/tests/plugins/common_test.py similarity index 99% rename from certbot/plugins/common_test.py rename to certbot/tests/plugins/common_test.py index 5d529e993..fc05bf894 100644 --- a/certbot/plugins/common_test.py +++ b/certbot/tests/plugins/common_test.py @@ -7,12 +7,11 @@ import josepy as jose import mock from acme import challenges - from certbot import achallenges from certbot import crypto_util from certbot import errors -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os from certbot.tests import acme_util from certbot.tests import util as test_util diff --git a/certbot/plugins/disco_test.py b/certbot/tests/plugins/disco_test.py similarity index 99% rename from certbot/plugins/disco_test.py rename to certbot/tests/plugins/disco_test.py index f739512f0..6d3c7d97e 100644 --- a/certbot/plugins/disco_test.py +++ b/certbot/tests/plugins/disco_test.py @@ -11,7 +11,6 @@ import zope.interface from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module from certbot import errors from certbot import interfaces - from certbot._internal.plugins import standalone from certbot._internal.plugins import webroot diff --git a/certbot/plugins/dns_common_lexicon_test.py b/certbot/tests/plugins/dns_common_lexicon_test.py similarity index 100% rename from certbot/plugins/dns_common_lexicon_test.py rename to certbot/tests/plugins/dns_common_lexicon_test.py diff --git a/certbot/plugins/dns_common_test.py b/certbot/tests/plugins/dns_common_test.py similarity index 100% rename from certbot/plugins/dns_common_test.py rename to certbot/tests/plugins/dns_common_test.py diff --git a/certbot/plugins/enhancements_test.py b/certbot/tests/plugins/enhancements_test.py similarity index 91% rename from certbot/plugins/enhancements_test.py rename to certbot/tests/plugins/enhancements_test.py index 86482184e..05fbc5028 100644 --- a/certbot/plugins/enhancements_test.py +++ b/certbot/tests/plugins/enhancements_test.py @@ -1,10 +1,10 @@ """Tests for new style enhancements""" import unittest + import mock -from certbot.plugins import enhancements from certbot._internal.plugins import null - +from certbot.plugins import enhancements import certbot.tests.util as test_util @@ -37,12 +37,10 @@ class EnhancementTest(test_util.ConfigTestCase): self.assertTrue([i for i in enabled if i["name"] == "somethingelse"]) def test_are_requested(self): - self.assertEqual( - len([i for i in enhancements.enabled_enhancements(self.config)]), 0) + self.assertEqual(len(list(enhancements.enabled_enhancements(self.config))), 0) self.assertFalse(enhancements.are_requested(self.config)) self.config.auto_hsts = True - self.assertEqual( - len([i for i in enhancements.enabled_enhancements(self.config)]), 1) + self.assertEqual(len(list(enhancements.enabled_enhancements(self.config))), 1) self.assertTrue(enhancements.are_requested(self.config)) def test_are_supported(self): diff --git a/certbot/plugins/manual_test.py b/certbot/tests/plugins/manual_test.py similarity index 99% rename from certbot/plugins/manual_test.py rename to certbot/tests/plugins/manual_test.py index 8796c30f1..bd11a9538 100644 --- a/certbot/plugins/manual_test.py +++ b/certbot/tests/plugins/manual_test.py @@ -1,15 +1,14 @@ """Tests for certbot._internal.plugins.manual""" -import unittest import sys +import unittest import mock import six from acme import challenges - from certbot import errors -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os from certbot.tests import acme_util from certbot.tests import util as test_util diff --git a/certbot/plugins/null_test.py b/certbot/tests/plugins/null_test.py similarity index 100% rename from certbot/plugins/null_test.py rename to certbot/tests/plugins/null_test.py index 41cd45a93..db0213813 100644 --- a/certbot/plugins/null_test.py +++ b/certbot/tests/plugins/null_test.py @@ -1,8 +1,8 @@ """Tests for certbot._internal.plugins.null.""" import unittest -import six import mock +import six class InstallerTest(unittest.TestCase): diff --git a/certbot/plugins/selection_test.py b/certbot/tests/plugins/selection_test.py similarity index 99% rename from certbot/plugins/selection_test.py rename to certbot/tests/plugins/selection_test.py index 9de7f7941..ac846af7b 100644 --- a/certbot/plugins/selection_test.py +++ b/certbot/tests/plugins/selection_test.py @@ -6,12 +6,11 @@ import mock import zope.component from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module - from certbot import errors from certbot import interfaces +from certbot._internal.plugins.disco import PluginsRegistry from certbot.compat import os from certbot.display import util as display_util -from certbot._internal.plugins.disco import PluginsRegistry from certbot.tests import util as test_util diff --git a/certbot/plugins/standalone_test.py b/certbot/tests/plugins/standalone_test.py similarity index 95% rename from certbot/plugins/standalone_test.py rename to certbot/tests/plugins/standalone_test.py index c9dabb8b4..5d9ff5244 100644 --- a/certbot/plugins/standalone_test.py +++ b/certbot/tests/plugins/standalone_test.py @@ -1,22 +1,21 @@ """Tests for certbot._internal.plugins.standalone.""" -import socket # https://github.com/python/typeshed/blob/master/stdlib/2and3/socket.pyi +import socket from socket import errno as socket_errors # type: ignore import unittest import josepy as jose import mock -import six - import OpenSSL.crypto # pylint: disable=unused-import +import six from acme import challenges from acme import standalone as acme_standalone # pylint: disable=unused-import -from acme.magic_typing import Dict, Tuple, Set # 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 Set # pylint: disable=unused-import, no-name-in-module +from acme.magic_typing import Tuple # pylint: disable=unused-import, no-name-in-module from certbot import achallenges from certbot import errors - from certbot.tests import acme_util from certbot.tests import util as test_util @@ -38,7 +37,7 @@ class ServerManagerTest(unittest.TestCase): def _test_run_stop(self, challenge_type): server = self.mgr.run(port=0, challenge_type=challenge_type) - port = server.getsocknames()[0][1] # pylint: disable=no-member + port = server.getsocknames()[0][1] self.assertEqual(self.mgr.running(), {port: server}) self.mgr.stop(port=port) self.assertEqual(self.mgr.running(), {}) @@ -48,7 +47,7 @@ class ServerManagerTest(unittest.TestCase): def test_run_idempotent(self): server = self.mgr.run(port=0, challenge_type=challenges.HTTP01) - port = server.getsocknames()[0][1] # pylint: disable=no-member + port = server.getsocknames()[0][1] server2 = self.mgr.run(port=port, challenge_type=challenges.HTTP01) self.assertEqual(self.mgr.running(), {port: server}) self.assertTrue(server is server2) diff --git a/certbot/plugins/storage_test.py b/certbot/tests/plugins/storage_test.py similarity index 100% rename from certbot/plugins/storage_test.py rename to certbot/tests/plugins/storage_test.py index 9d08cc7ef..e9ca2007f 100644 --- a/certbot/plugins/storage_test.py +++ b/certbot/tests/plugins/storage_test.py @@ -1,12 +1,12 @@ """Tests for certbot.plugins.storage.PluginStorage""" import json import unittest + import mock from certbot import errors - -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os from certbot.plugins import common from certbot.tests import util as test_util diff --git a/certbot/plugins/util_test.py b/certbot/tests/plugins/util_test.py similarity index 100% rename from certbot/plugins/util_test.py rename to certbot/tests/plugins/util_test.py diff --git a/certbot/plugins/webroot_test.py b/certbot/tests/plugins/webroot_test.py similarity index 99% rename from certbot/plugins/webroot_test.py rename to certbot/tests/plugins/webroot_test.py index 70501f812..fade12bb1 100644 --- a/certbot/plugins/webroot_test.py +++ b/certbot/tests/plugins/webroot_test.py @@ -14,11 +14,10 @@ import mock import six from acme import challenges - from certbot import achallenges from certbot import errors -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os from certbot.display import util as display_util from certbot.tests import acme_util from certbot.tests import util as test_util diff --git a/certbot/tests/renewal_test.py b/certbot/tests/renewal_test.py index 612a5fcb2..e92211ea2 100644 --- a/certbot/tests/renewal_test.py +++ b/certbot/tests/renewal_test.py @@ -1,18 +1,17 @@ """Tests for certbot._internal.renewal""" import unittest + import mock from acme import challenges - -from certbot import configuration from certbot import errors +from certbot._internal import configuration from certbot._internal import storage - import certbot.tests.util as test_util class RenewalTest(test_util.ConfigTestCase): - @mock.patch('certbot.cli.set_by_cli') + @mock.patch('certbot._internal.cli.set_by_cli') def test_ancient_webroot_renewal_conf(self, mock_set_by_cli): mock_set_by_cli.return_value = False rc_path = test_util.make_lineage( diff --git a/certbot/tests/renewupdater_test.py b/certbot/tests/renewupdater_test.py index 42b723c94..c6f8f3713 100644 --- a/certbot/tests/renewupdater_test.py +++ b/certbot/tests/renewupdater_test.py @@ -1,13 +1,12 @@ """Tests for renewal updater interfaces""" import unittest + import mock from certbot import interfaces from certbot._internal import main from certbot._internal import updater - from certbot.plugins import enhancements - import certbot.tests.util as test_util diff --git a/certbot/tests/reporter_test.py b/certbot/tests/reporter_test.py index a30aaeb8c..3d7c80172 100644 --- a/certbot/tests/reporter_test.py +++ b/certbot/tests/reporter_test.py @@ -1,8 +1,8 @@ """Tests for certbot._internal.reporter.""" import sys import unittest -import mock +import mock import six diff --git a/certbot/tests/reverter_test.py b/certbot/tests/reverter_test.py index 3ba628475..fc9133c5f 100644 --- a/certbot/tests/reverter_test.py +++ b/certbot/tests/reverter_test.py @@ -14,7 +14,6 @@ from certbot.tests import util as test_util class ReverterCheckpointLocalTest(test_util.ConfigTestCase): - # pylint: disable=too-many-instance-attributes, too-many-public-methods """Test the Reverter Class.""" def setUp(self): super(ReverterCheckpointLocalTest, self).setUp() @@ -277,7 +276,6 @@ class ReverterCheckpointLocalTest(test_util.ConfigTestCase): class TestFullCheckpointsReverter(test_util.ConfigTestCase): - # pylint: disable=too-many-instance-attributes """Tests functions having to deal with full checkpoints.""" def setUp(self): super(TestFullCheckpointsReverter, self).setUp() diff --git a/certbot/tests/storage_test.py b/certbot/tests/storage_test.py index 0c525fcc6..6208974ec 100644 --- a/certbot/tests/storage_test.py +++ b/certbot/tests/storage_test.py @@ -11,11 +11,11 @@ import pytz import six import certbot -import certbot.tests.util as test_util from certbot import errors -from certbot.compat import os -from certbot.compat import filesystem from certbot._internal.storage import ALL_FOUR +from certbot.compat import filesystem +from certbot.compat import os +import certbot.tests.util as test_util CERT = test_util.load_cert('cert_512.pem') @@ -43,7 +43,7 @@ class RelevantValuesTest(unittest.TestCase): from certbot._internal.storage import relevant_values return relevant_values(*args, **kwargs) - @mock.patch("certbot.cli.option_was_set") + @mock.patch("certbot._internal.cli.option_was_set") @mock.patch("certbot._internal.plugins.disco.PluginsRegistry.find_all") def test_namespace(self, mock_find_all, mock_option_was_set): mock_find_all.return_value = ["certbot-foo:bar"] @@ -53,7 +53,7 @@ class RelevantValuesTest(unittest.TestCase): self.assertEqual( self._call(self.values.copy()), self.values) - @mock.patch("certbot.cli.option_was_set") + @mock.patch("certbot._internal.cli.option_was_set") def test_option_set(self, mock_option_was_set): mock_option_was_set.return_value = True @@ -65,7 +65,7 @@ class RelevantValuesTest(unittest.TestCase): self.assertEqual(self._call(self.values), expected_relevant_values) - @mock.patch("certbot.cli.option_was_set") + @mock.patch("certbot._internal.cli.option_was_set") def test_option_unset(self, mock_option_was_set): mock_option_was_set.return_value = False @@ -140,7 +140,6 @@ class BaseRenewableCertTest(test_util.ConfigTestCase): class RenewableCertTests(BaseRenewableCertTest): - # pylint: disable=too-many-public-methods """Tests for certbot._internal.storage.""" def test_initialization(self): @@ -202,7 +201,7 @@ class RenewableCertTests(BaseRenewableCertTest): self.assertTrue("version" in mock_logger.info.call_args[0][0]) def test_consistent(self): - # pylint: disable=too-many-statements,protected-access + # pylint: disable=protected-access oldcert = self.test_rc.cert self.test_rc.cert = "relative/path" # Absolute path for item requirement @@ -357,8 +356,7 @@ class RenewableCertTests(BaseRenewableCertTest): basename = os.path.basename(path) if "fullchain" in basename and basename.startswith("prev"): raise ValueError - else: - real_unlink(path) + real_unlink(path) self._write_out_ex_kinds() with mock.patch("certbot._internal.storage.os.unlink") as mock_unlink: @@ -373,8 +371,7 @@ class RenewableCertTests(BaseRenewableCertTest): # pylint: disable=missing-docstring if "fullchain" in os.path.basename(path): raise ValueError - else: - real_unlink(path) + real_unlink(path) self._write_out_ex_kinds() with mock.patch("certbot._internal.storage.os.unlink") as mock_unlink: @@ -405,20 +402,6 @@ class RenewableCertTests(BaseRenewableCertTest): self.assertEqual(self.test_rc.names(), ["example.com", "www.example.com"]) - # Trying a non-current version - self._write_out_kind("cert", 15, test_util.load_vector("cert_512.pem")) - - self.assertEqual(self.test_rc.names(12), - ["example.com", "www.example.com"]) - - # Testing common name is listed first - self._write_out_kind( - "cert", 12, test_util.load_vector("cert-5sans_512.pem")) - - self.assertEqual( - self.test_rc.names(12), - ["example.com"] + ["{0}.example.com".format(c) for c in "abcd"]) - # Trying missing cert os.unlink(self.test_rc.cert) self.assertRaises(errors.CertStorageError, self.test_rc.names) @@ -483,7 +466,6 @@ class RenewableCertTests(BaseRenewableCertTest): def test_should_autorenew(self, mock_ocsp, mock_cli): """Test should_autorenew on the basis of reasons other than expiry time window.""" - # pylint: disable=too-many-statements mock_cli.set_by_cli.return_value = False # Autorenewal turned off self.test_rc.configuration["renewalparams"] = {"autorenew": "False"} diff --git a/certbot/tests/util_test.py b/certbot/tests/util_test.py index 5ced9f78e..ae061de65 100644 --- a/certbot/tests/util_test.py +++ b/certbot/tests/util_test.py @@ -8,10 +8,10 @@ import mock import six from six.moves import reload_module # pylint: disable=import-error -import certbot.tests.util as test_util from certbot import errors -from certbot.compat import os from certbot.compat import filesystem +from certbot.compat import os +import certbot.tests.util as test_util class RunScriptTest(unittest.TestCase): diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index ba65b13af..000000000 --- a/docs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/_build/ diff --git a/docs/_static/.gitignore b/docs/_static/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/api.rst b/docs/api.rst deleted file mode 100644 index 8668ec5d8..000000000 --- a/docs/api.rst +++ /dev/null @@ -1,8 +0,0 @@ -================= -API Documentation -================= - -.. toctree:: - :glob: - - api/** diff --git a/docs/api/achallenges.rst b/docs/api/achallenges.rst deleted file mode 100644 index 90dda3f06..000000000 --- a/docs/api/achallenges.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.achallenges` ------------------------------- - -.. automodule:: certbot.achallenges - :members: diff --git a/docs/api/cli.rst b/docs/api/cli.rst deleted file mode 100644 index 91be86758..000000000 --- a/docs/api/cli.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.cli` ----------------------- - -.. automodule:: certbot.cli - :members: diff --git a/docs/api/configuration.rst b/docs/api/configuration.rst deleted file mode 100644 index 4e99c73d2..000000000 --- a/docs/api/configuration.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.configuration` --------------------------------- - -.. automodule:: certbot.configuration - :members: diff --git a/docs/api/crypto_util.rst b/docs/api/crypto_util.rst deleted file mode 100644 index 2f473944c..000000000 --- a/docs/api/crypto_util.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.crypto_util` ------------------------------- - -.. automodule:: certbot.crypto_util - :members: diff --git a/docs/api/display.rst b/docs/api/display.rst deleted file mode 100644 index 70038786c..000000000 --- a/docs/api/display.rst +++ /dev/null @@ -1,17 +0,0 @@ -:mod:`certbot.display` --------------------------- - -.. automodule:: certbot.display - :members: - -:mod:`certbot.display.util` -=============================== - -.. automodule:: certbot.display.util - :members: - -:mod:`certbot.display.ops` -============================== - -.. automodule:: certbot.display.ops - :members: diff --git a/docs/api/errors.rst b/docs/api/errors.rst deleted file mode 100644 index a9324765b..000000000 --- a/docs/api/errors.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.errors` -------------------------- - -.. automodule:: certbot.errors - :members: diff --git a/docs/api/hooks.rst b/docs/api/hooks.rst deleted file mode 100644 index 140fbf284..000000000 --- a/docs/api/hooks.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.hooks` ------------------------- - -.. automodule:: certbot.hooks - :members: diff --git a/docs/api/index.rst b/docs/api/index.rst deleted file mode 100644 index be94214c9..000000000 --- a/docs/api/index.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot` ------------------- - -.. automodule:: certbot - :members: diff --git a/docs/api/interfaces.rst b/docs/api/interfaces.rst deleted file mode 100644 index 2988b3b87..000000000 --- a/docs/api/interfaces.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.interfaces` ------------------------------ - -.. automodule:: certbot.interfaces - :members: diff --git a/docs/api/plugins/common.rst b/docs/api/plugins/common.rst deleted file mode 100644 index 7cfaf8d70..000000000 --- a/docs/api/plugins/common.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.plugins.common` ---------------------------------- - -.. automodule:: certbot.plugins.common - :members: diff --git a/docs/api/plugins/dns_common.rst b/docs/api/plugins/dns_common.rst deleted file mode 100644 index ee3945e74..000000000 --- a/docs/api/plugins/dns_common.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.plugins.dns_common` ---------------------------------- - -.. automodule:: certbot.plugins.dns_common - :members: diff --git a/docs/api/plugins/dns_common_lexicon.rst b/docs/api/plugins/dns_common_lexicon.rst deleted file mode 100644 index a48166828..000000000 --- a/docs/api/plugins/dns_common_lexicon.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.plugins.dns_common_lexicon` ------------------------------------------ - -.. automodule:: certbot.plugins.dns_common_lexicon - :members: diff --git a/docs/api/plugins/util.rst b/docs/api/plugins/util.rst deleted file mode 100644 index 30ab3d49f..000000000 --- a/docs/api/plugins/util.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.plugins.util` -------------------------------- - -.. automodule:: certbot.plugins.util - :members: diff --git a/docs/api/reverter.rst b/docs/api/reverter.rst deleted file mode 100644 index 3e0ac750b..000000000 --- a/docs/api/reverter.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.reverter` ---------------------------- - -.. automodule:: certbot.reverter - :members: diff --git a/docs/api/util.rst b/docs/api/util.rst deleted file mode 100644 index 7d0e33501..000000000 --- a/docs/api/util.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`certbot.util` --------------------------- - -.. automodule:: certbot.util - :members: diff --git a/letsencrypt-auto b/letsencrypt-auto index 9f3d2af08..2d3f4cfef 100755 --- a/letsencrypt-auto +++ b/letsencrypt-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="0.40.1" +LE_AUTO_VERSION="1.1.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 @@ -1145,63 +1276,70 @@ if [ "$1" = "--le-auto-phase2" ]; then # ``` ConfigArgParse==0.14.0 \ --hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91 -asn1crypto==0.24.0 \ - --hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \ - --hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49 -certifi==2019.6.16 \ - --hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \ - --hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695 -cffi==1.12.3 \ - --hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \ - --hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \ - --hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \ - --hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \ - --hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \ - --hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \ - --hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \ - --hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \ - --hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \ - --hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \ - --hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \ - --hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \ - --hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \ - --hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \ - --hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \ - --hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \ - --hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \ - --hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \ - --hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \ - --hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \ - --hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \ - --hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \ - --hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \ - --hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \ - --hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \ - --hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \ - --hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \ - --hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201 +certifi==2019.9.11 \ + --hash=sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50 \ + --hash=sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef +cffi==1.13.2 \ + --hash=sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42 \ + --hash=sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04 \ + --hash=sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5 \ + --hash=sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54 \ + --hash=sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba \ + --hash=sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57 \ + --hash=sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396 \ + --hash=sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12 \ + --hash=sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97 \ + --hash=sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43 \ + --hash=sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db \ + --hash=sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3 \ + --hash=sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b \ + --hash=sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579 \ + --hash=sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346 \ + --hash=sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159 \ + --hash=sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652 \ + --hash=sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e \ + --hash=sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a \ + --hash=sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506 \ + --hash=sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f \ + --hash=sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d \ + --hash=sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c \ + --hash=sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20 \ + --hash=sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858 \ + --hash=sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc \ + --hash=sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a \ + --hash=sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3 \ + --hash=sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e \ + --hash=sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410 \ + --hash=sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25 \ + --hash=sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b \ + --hash=sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d chardet==3.0.4 \ --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \ --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 -cryptography==2.7 \ - --hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \ - --hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \ - --hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \ - --hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \ - --hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \ - --hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \ - --hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \ - --hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \ - --hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \ - --hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \ - --hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \ - --hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \ - --hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \ - --hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \ - --hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \ - --hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d +cryptography==2.8 \ + --hash=sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c \ + --hash=sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595 \ + --hash=sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad \ + --hash=sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651 \ + --hash=sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2 \ + --hash=sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff \ + --hash=sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d \ + --hash=sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42 \ + --hash=sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d \ + --hash=sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e \ + --hash=sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912 \ + --hash=sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793 \ + --hash=sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13 \ + --hash=sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7 \ + --hash=sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0 \ + --hash=sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879 \ + --hash=sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f \ + --hash=sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9 \ + --hash=sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2 \ + --hash=sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf \ + --hash=sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8 distro==1.4.0 \ --hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \ --hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4 @@ -1213,14 +1351,14 @@ enum34==1.1.6 \ funcsigs==1.0.2 \ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \ --hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50 -future==0.17.1 \ - --hash=sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8 +future==0.18.2 \ + --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d idna==2.8 \ --hash=sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407 \ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c -ipaddress==1.0.22 \ - --hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \ - --hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c +ipaddress==1.0.23 \ + --hash=sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc \ + --hash=sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2 josepy==1.2.0 \ --hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \ --hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3 @@ -1230,9 +1368,9 @@ mock==1.3.0 \ parsedatetime==2.4 \ --hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \ --hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094 -pbr==5.4.2 \ - --hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \ - --hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf +pbr==5.4.3 \ + --hash=sha256:2c8e420cd4ed4cec4e7999ee47409e876af575d4c35a45840d59e8b5f3155ab8 \ + --hash=sha256:b32c8ccaac7b1a20c0ce00ce317642e6cf231cf038f9875e0280e28af5bf7ac9 pyOpenSSL==19.0.0 \ --hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \ --hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6 @@ -1241,29 +1379,28 @@ pyRFC3339==1.1 \ --hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a pycparser==2.19 \ --hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3 -pyparsing==2.4.2 \ - --hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \ - --hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4 +pyparsing==2.4.5 \ + --hash=sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f \ + --hash=sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a python-augeas==0.5.0 \ --hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2 -pytz==2019.2 \ - --hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \ - --hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7 +pytz==2019.3 \ + --hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \ + --hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be requests==2.21.0 \ --hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \ --hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b requests-toolbelt==0.9.1 \ --hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \ --hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0 -six==1.12.0 \ - --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \ - --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 +six==1.13.0 \ + --hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \ + --hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66 urllib3==1.24.3 \ --hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \ --hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb -zope.component==4.5 \ - --hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \ - --hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4 +zope.component==4.6 \ + --hash=sha256:ec2afc5bbe611dcace98bb39822c122d44743d635dafc7315b9aef25097db9e6 zope.deferredimport==4.3.1 \ --hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \ --hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a @@ -1314,18 +1451,46 @@ zope.interface==4.6.0 \ --hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \ --hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \ --hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317 -zope.proxy==4.3.2 \ - --hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \ - --hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \ - --hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \ - --hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \ - --hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \ - --hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \ - --hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \ - --hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \ - --hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \ - --hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \ - --hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366 +zope.proxy==4.3.3 \ + --hash=sha256:04646ac04ffa9c8e32fb2b5c3cd42995b2548ea14251f3c21ca704afae88e42c \ + --hash=sha256:07b6bceea232559d24358832f1cd2ed344bbf05ca83855a5b9698b5f23c5ed60 \ + --hash=sha256:1ef452cc02e0e2f8e3c917b1a5b936ef3280f2c2ca854ee70ac2164d1655f7e6 \ + --hash=sha256:22bf61857c5977f34d4e391476d40f9a3b8c6ab24fb0cac448d42d8f8b9bf7b2 \ + --hash=sha256:299870e3428cbff1cd9f9b34144e76ecdc1d9e3192a8cf5f1b0258f47a239f58 \ + --hash=sha256:2bfc36bfccbe047671170ea5677efd3d5ab730a55d7e45611d76d495e5b96766 \ + --hash=sha256:32e82d5a640febc688c0789e15ea875bf696a10cf358f049e1ed841f01710a9b \ + --hash=sha256:3b2051bdc4bc3f02fa52483f6381cf40d4d48167645241993f9d7ebbd142ed9b \ + --hash=sha256:3f734bd8a08f5185a64fb6abb8f14dc97ec27a689ca808fb7a83cdd38d745e4f \ + --hash=sha256:3f78dd8de3112df8bbd970f0916ac876dc3fbe63810bd1cf7cc5eec4cbac4f04 \ + --hash=sha256:4eabeb48508953ba1f3590ad0773b8daea9e104eec66d661917e9bbcd7125a67 \ + --hash=sha256:4f05ecc33808187f430f249cb1ccab35c38f570b181f2d380fbe253da94b18d8 \ + --hash=sha256:4f4f4cbf23d3afc1526294a31e7b3eaa0f682cc28ac5366065dc1d6bb18bd7be \ + --hash=sha256:5483d5e70aacd06f0aa3effec9fed597c0b50f45060956eeeb1203c44d4338c3 \ + --hash=sha256:56a5f9b46892b115a75d0a1f2292431ad5988461175826600acc69a24cb3edee \ + --hash=sha256:64bb63af8a06f736927d260efdd4dfc5253d42244f281a8063e4b9eea2ddcbc5 \ + --hash=sha256:653f8cbefcf7c6ac4cece2cdef367c4faa2b7c19795d52bd7cbec11a8739a7c1 \ + --hash=sha256:664211d63306e4bd4eec35bf2b4bd9db61c394037911cf2d1804c43b511a49f1 \ + --hash=sha256:6651e6caed66a8fff0fef1a3e81c0ed2253bf361c0fdc834500488732c5d16e9 \ + --hash=sha256:6c1fba6cdfdf105739d3069cf7b07664f2944d82a8098218ab2300a82d8f40fc \ + --hash=sha256:6e64246e6e9044a4534a69dca1283c6ddab6e757be5e6874f69024329b3aa61f \ + --hash=sha256:838390245c7ec137af4993c0c8052f49d5ec79e422b4451bfa37fee9b9ccaa01 \ + --hash=sha256:856b410a14793069d8ba35f33fff667213ea66f2df25a0024cc72a7493c56d4c \ + --hash=sha256:8b932c364c1d1605a91907a41128ed0ee8a2d326fc0fafb2c55cd46f545f4599 \ + --hash=sha256:9086cf6d20f08dae7f296a78f6c77d1f8d24079d448f023ee0eb329078dd35e1 \ + --hash=sha256:9698533c14afa0548188de4968a7932d1f3f965f3f5ba1474de673596bb875af \ + --hash=sha256:9b12b05dd7c28f5068387c1afee8cb94f9d02501e7ef495a7c5c7e27139b96ad \ + --hash=sha256:a884c7426a5bc6fb7fc71a55ad14e66818e13f05b78b20a6f37175f324b7acb8 \ + --hash=sha256:abe9e7f1a3e76286c5f5baf2bf5162d41dc0310da493b34a2c36555f38d928f7 \ + --hash=sha256:bd6fde63b015a27262be06bd6bbdd895273cc2bdf2d4c7e1c83711d26a8fbace \ + --hash=sha256:bda7c62c954f47b87ed9a89f525eee1b318ec7c2162dfdba76c2ccfa334e0caa \ + --hash=sha256:be8a4908dd3f6e965993c0068b006bdbd0474fbcbd1da4893b49356e73fc1557 \ + --hash=sha256:ced65fc3c7d7205267506d854bb1815bb445899cca9d21d1d4b949070a635546 \ + --hash=sha256:dac4279aa05055d3897ab5e5ee5a7b39db121f91df65a530f8b1ac7f9bd93119 \ + --hash=sha256:e4f1863056e3e4f399c285b67fa816f411a7bfa1c81ef50e186126164e396e59 \ + --hash=sha256:ecd85f68b8cd9ab78a0141e87ea9a53b2f31fd9b1350a1c44da1f7481b5363ef \ + --hash=sha256:ed269b83750413e8fc5c96276372f49ee3fcb7ed61c49fe8e5a67f54459a5a4a \ + --hash=sha256:f19b0b80cba73b204dee68501870b11067711d21d243fb6774256d3ca2e5391f \ + --hash=sha256:ffdafb98db7574f9da84c489a10a5d582079a888cb43c64e9e6b0e3fe1034685 # Contains the requirements for the letsencrypt package. # @@ -1338,18 +1503,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==0.40.1 \ - --hash=sha256:afe4d7edc61d4cab8b6f7ab7611d66aaba67d9f0404fa2760bd1cc430b2ec9ec \ - --hash=sha256:8dc81b3044cf401c55fa36c30893887fcb92657df1d76a8848059683df3b10d1 -acme==0.40.1 \ - --hash=sha256:a85387c26fb4fc24511b2579b8c61177b3175fd25e130c5be95a840d9f67d54f \ - --hash=sha256:33bf8686408d5b6b79886a9a43aee691ca754408deaec4fb2bb17b9af48a5ffc -certbot-apache==0.40.1 \ - --hash=sha256:6c4a4e21a17bd8120056595e5670c9a0f86756da0ad269196e8d56fc1b9fec82 \ - --hash=sha256:16404e9e404f0b98c18bd752fad812a45ef7f9b0efa9bbc8589f24a94e67de7c -certbot-nginx==0.40.1 \ - --hash=sha256:acdbfc4ab75ebc810264ee1248332f8e857c5e7776717b7cd53c4ceceb2b4d34 \ - --hash=sha256:014fdda80647ad9e67019b16c7cdaee5d21a750b393bcb98e1300615cc930f4f +certbot==1.1.0 \ + --hash=sha256:66a5cab9267349941604c2c98082bfef85877653c023fc324b1c3869fb16add6 \ + --hash=sha256:46e93661a0db53f416c0f5476d8d2e62bc7259b7660dd983453b85df9ef6e8b8 +acme==1.1.0 \ + --hash=sha256:11b9beba706fb8f652c8910d46dd1939d670cac8169f3c66c18c080ed3353e71 \ + --hash=sha256:c305a20eeb9cb02240347703d497891c13d43a47c794fa100d4dbb479a5370d9 +certbot-apache==1.1.0 \ + --hash=sha256:9c847ff223c2e465e241c78d22f97cee77d5e551df608bed06c55f8627f4cbd2 \ + --hash=sha256:05e84dfe96b72582cde97c490977d8e2d33d440c927a320debb4cf287f6fadcc +certbot-nginx==1.1.0 \ + --hash=sha256:bf06fa2f5059f0fdb7d352c8739e1ed0830db4f0d89e812dab4f081bda6ec7d6 \ + --hash=sha256:0a80ecbd2a30f3757c7652cabfff854ca07873b1cf02ebbe1892786c3b3a5874 UNLIKELY_EOF # ------------------------------------------------------------------------- @@ -1583,6 +1748,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 @@ -1794,30 +1962,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 "$@" diff --git a/letsencrypt-auto-source/Dockerfile.centos6 b/letsencrypt-auto-source/Dockerfile.centos6 deleted file mode 100644 index 09aa52dcd..000000000 --- a/letsencrypt-auto-source/Dockerfile.centos6 +++ /dev/null @@ -1,37 +0,0 @@ -# For running tests, build a docker image with a passwordless sudo and a trust -# store we can manipulate. - -FROM centos:6 - -RUN yum install -y epel-release - -# Install pip and sudo: -RUN yum install -y python-pip sudo -# Update to a stable and tested version of pip. -# We do not use pipstrap here because it no longer supports Python 2.6. -RUN pip install pip==9.0.1 setuptools==29.0.1 wheel==0.29.0 -# Pin pytest version for increased stability -RUN pip install pytest==3.2.5 six==1.10.0 - -# Add an unprivileged user: -RUN useradd --create-home --home-dir /home/lea --shell /bin/bash --groups wheel --uid 1000 lea - -# Let that user sudo: -RUN sed -i.bkp -e \ - 's/# %wheel\(NOPASSWD: ALL\)\?/%wheel/g' \ - /etc/sudoers - -RUN mkdir -p /home/lea/certbot - -# Install fake testing CA: -COPY ./tests/certs/ca/my-root-ca.crt.pem /usr/local/share/ca-certificates/ -RUN update-ca-trust - -# Copy code: -COPY . /home/lea/certbot/letsencrypt-auto-source - -USER lea -WORKDIR /home/lea - -RUN sudo chmod +x certbot/letsencrypt-auto-source/tests/centos6_tests.sh -CMD sudo certbot/letsencrypt-auto-source/tests/centos6_tests.sh diff --git a/letsencrypt-auto-source/Dockerfile.redhat6 b/letsencrypt-auto-source/Dockerfile.redhat6 new file mode 100644 index 000000000..66f21bc14 --- /dev/null +++ b/letsencrypt-auto-source/Dockerfile.redhat6 @@ -0,0 +1,54 @@ +# For running tests, build a docker image with a passwordless sudo and a trust +# store we can manipulate. + +ARG REDHAT_DIST_FLAVOR +FROM ${REDHAT_DIST_FLAVOR}:6 + +ARG REDHAT_DIST_FLAVOR + +RUN curl -O https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm \ + && rpm -ivh epel-release-latest-6.noarch.rpm + +# Install pip and sudo: +RUN yum install -y python-pip sudo +# Update to a stable and tested version of pip. +# We do not use pipstrap here because it no longer supports Python 2.6. +RUN pip install pip==9.0.1 setuptools==29.0.1 wheel==0.29.0 +# Pin pytest version for increased stability +RUN pip install pytest==3.2.5 six==1.10.0 + +# Add an unprivileged user: +RUN useradd --create-home --home-dir /home/lea --shell /bin/bash --groups wheel --uid 1000 lea + +# Let that user sudo: +RUN sed -i.bkp -e \ + 's/# %wheel\(NOPASSWD: ALL\)\?/%wheel/g' \ + /etc/sudoers + +RUN mkdir -p /home/lea/certbot + +# Install fake testing CA: +COPY ./tests/certs/ca/my-root-ca.crt.pem /usr/local/share/ca-certificates/ +RUN update-ca-trust + +# Copy current letsencrypt-auto: +COPY . /home/lea/certbot/letsencrypt-auto-source + +# Tweak uname binary for tests on fake 32bits +COPY tests/uname_wrapper.sh /bin +RUN mv /bin/uname /bin/uname_orig \ + && mv /bin/uname_wrapper.sh /bin/uname \ + && chmod +x /bin/uname + +# Fetch previous letsencrypt-auto that was installing python 3.4 +RUN curl https://raw.githubusercontent.com/certbot/certbot/v0.38.0/letsencrypt-auto-source/letsencrypt-auto \ + -o /home/lea/certbot/letsencrypt-auto-source/letsencrypt-auto_py_34 \ + && chmod +x /home/lea/certbot/letsencrypt-auto-source/letsencrypt-auto_py_34 + +RUN cp /home/lea/certbot/letsencrypt-auto-source/tests/${REDHAT_DIST_FLAVOR}6_tests.sh /home/lea/certbot/letsencrypt-auto-source/tests/redhat6_tests.sh \ + && chmod +x /home/lea/certbot/letsencrypt-auto-source/tests/redhat6_tests.sh + +USER lea +WORKDIR /home/lea + +CMD ["sudo", "certbot/letsencrypt-auto-source/tests/redhat6_tests.sh"] diff --git a/letsencrypt-auto-source/certbot-auto.asc b/letsencrypt-auto-source/certbot-auto.asc index 2c7986ea9..1a030eb47 100644 --- a/letsencrypt-auto-source/certbot-auto.asc +++ b/letsencrypt-auto-source/certbot-auto.asc @@ -1,11 +1,11 @@ -----BEGIN PGP SIGNATURE----- -iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAl3CMH0ACgkQTRfJlc2X -dfJ4DwgAljOxkQ4uhiF1R8Mw3r5+lwSezh7seA01QVUcuLArZM8B+IJM0FbqrSca -ToYCrUXXTVL6aPn/1yxuNMMmVlJbIl5tMc3tfm//lbXTpLkiVASZl5+3HKtR5o6w -GP2v6apjvkM1oaT2jL0VKcMGheVYaLfUQ3MGhMHbgOZKALNYwMGP9WOwgn0GGa1l -3SIYJOqgEjDQTSr1tK+Ki+UkuoMsL4HamfvgNWeXbTpChdjth46UTj+N60rafIA2 -HAkXoP4eav6XbDlzDulG2cTBtnxvr6yiK76YF68P7BHNNYWbybFW8k6TVwexGgDF -2di01Av0nXsa4O8QkYdtVQcCgniaUw== -=E9YT +iQEzBAABCAAdFiEEos+1H6J1pyhiNOeyTRfJlc2XdfIFAl4eDcYACgkQTRfJlc2X +dfIAiQgAufTpgNvnHKoLQLwWf3GbjLQYWc3w1zRbGUMjghS/rS1yuf7RE/IPItET +ocIuIE36ogjvgnRuI0OOu3yJ+jxe41u3ToPb0ehNhINd+3rXsDhzwJDPjFdOiq98 +NoW9wQE9AHSfKEEVprckuZe2XmNLsYbBfa9THFULYIlnqAewtercXXx0eKaMG9+d +aRaD+LZXANx7IV6XnI9jfdKRuldHDvYp1TdvrRWBAVHid8j44c3P0pSvzf0YKGbx +xIty/w0zQFIWCfqPdK7/R2EHbEyR0SdI00a1Va1x7P8JGf7kDyLXl+Y9Yth7/uHA +osivJCpSrtAEbvMXojnL7u7kq3b37Q== +=Une9 -----END PGP SIGNATURE----- diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 386d19531..17badacc7 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-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.dev0" +LE_AUTO_VERSION="1.2.0.dev0" 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 @@ -1145,63 +1276,70 @@ if [ "$1" = "--le-auto-phase2" ]; then # ``` ConfigArgParse==0.14.0 \ --hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91 -asn1crypto==0.24.0 \ - --hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \ - --hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49 -certifi==2019.6.16 \ - --hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \ - --hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695 -cffi==1.12.3 \ - --hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \ - --hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \ - --hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \ - --hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \ - --hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \ - --hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \ - --hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \ - --hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \ - --hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \ - --hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \ - --hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \ - --hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \ - --hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \ - --hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \ - --hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \ - --hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \ - --hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \ - --hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \ - --hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \ - --hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \ - --hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \ - --hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \ - --hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \ - --hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \ - --hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \ - --hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \ - --hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \ - --hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201 +certifi==2019.9.11 \ + --hash=sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50 \ + --hash=sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef +cffi==1.13.2 \ + --hash=sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42 \ + --hash=sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04 \ + --hash=sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5 \ + --hash=sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54 \ + --hash=sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba \ + --hash=sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57 \ + --hash=sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396 \ + --hash=sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12 \ + --hash=sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97 \ + --hash=sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43 \ + --hash=sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db \ + --hash=sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3 \ + --hash=sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b \ + --hash=sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579 \ + --hash=sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346 \ + --hash=sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159 \ + --hash=sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652 \ + --hash=sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e \ + --hash=sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a \ + --hash=sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506 \ + --hash=sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f \ + --hash=sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d \ + --hash=sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c \ + --hash=sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20 \ + --hash=sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858 \ + --hash=sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc \ + --hash=sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a \ + --hash=sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3 \ + --hash=sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e \ + --hash=sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410 \ + --hash=sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25 \ + --hash=sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b \ + --hash=sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d chardet==3.0.4 \ --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \ --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 -cryptography==2.7 \ - --hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \ - --hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \ - --hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \ - --hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \ - --hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \ - --hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \ - --hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \ - --hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \ - --hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \ - --hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \ - --hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \ - --hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \ - --hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \ - --hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \ - --hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \ - --hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d +cryptography==2.8 \ + --hash=sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c \ + --hash=sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595 \ + --hash=sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad \ + --hash=sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651 \ + --hash=sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2 \ + --hash=sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff \ + --hash=sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d \ + --hash=sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42 \ + --hash=sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d \ + --hash=sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e \ + --hash=sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912 \ + --hash=sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793 \ + --hash=sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13 \ + --hash=sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7 \ + --hash=sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0 \ + --hash=sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879 \ + --hash=sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f \ + --hash=sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9 \ + --hash=sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2 \ + --hash=sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf \ + --hash=sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8 distro==1.4.0 \ --hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \ --hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4 @@ -1213,14 +1351,14 @@ enum34==1.1.6 \ funcsigs==1.0.2 \ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \ --hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50 -future==0.17.1 \ - --hash=sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8 +future==0.18.2 \ + --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d idna==2.8 \ --hash=sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407 \ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c -ipaddress==1.0.22 \ - --hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \ - --hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c +ipaddress==1.0.23 \ + --hash=sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc \ + --hash=sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2 josepy==1.2.0 \ --hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \ --hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3 @@ -1230,9 +1368,9 @@ mock==1.3.0 \ parsedatetime==2.4 \ --hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \ --hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094 -pbr==5.4.2 \ - --hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \ - --hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf +pbr==5.4.3 \ + --hash=sha256:2c8e420cd4ed4cec4e7999ee47409e876af575d4c35a45840d59e8b5f3155ab8 \ + --hash=sha256:b32c8ccaac7b1a20c0ce00ce317642e6cf231cf038f9875e0280e28af5bf7ac9 pyOpenSSL==19.0.0 \ --hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \ --hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6 @@ -1241,29 +1379,28 @@ pyRFC3339==1.1 \ --hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a pycparser==2.19 \ --hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3 -pyparsing==2.4.2 \ - --hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \ - --hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4 +pyparsing==2.4.5 \ + --hash=sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f \ + --hash=sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a python-augeas==0.5.0 \ --hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2 -pytz==2019.2 \ - --hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \ - --hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7 +pytz==2019.3 \ + --hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \ + --hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be requests==2.21.0 \ --hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \ --hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b requests-toolbelt==0.9.1 \ --hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \ --hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0 -six==1.12.0 \ - --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \ - --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 +six==1.13.0 \ + --hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \ + --hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66 urllib3==1.24.3 \ --hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \ --hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb -zope.component==4.5 \ - --hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \ - --hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4 +zope.component==4.6 \ + --hash=sha256:ec2afc5bbe611dcace98bb39822c122d44743d635dafc7315b9aef25097db9e6 zope.deferredimport==4.3.1 \ --hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \ --hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a @@ -1314,18 +1451,46 @@ zope.interface==4.6.0 \ --hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \ --hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \ --hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317 -zope.proxy==4.3.2 \ - --hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \ - --hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \ - --hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \ - --hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \ - --hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \ - --hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \ - --hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \ - --hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \ - --hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \ - --hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \ - --hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366 +zope.proxy==4.3.3 \ + --hash=sha256:04646ac04ffa9c8e32fb2b5c3cd42995b2548ea14251f3c21ca704afae88e42c \ + --hash=sha256:07b6bceea232559d24358832f1cd2ed344bbf05ca83855a5b9698b5f23c5ed60 \ + --hash=sha256:1ef452cc02e0e2f8e3c917b1a5b936ef3280f2c2ca854ee70ac2164d1655f7e6 \ + --hash=sha256:22bf61857c5977f34d4e391476d40f9a3b8c6ab24fb0cac448d42d8f8b9bf7b2 \ + --hash=sha256:299870e3428cbff1cd9f9b34144e76ecdc1d9e3192a8cf5f1b0258f47a239f58 \ + --hash=sha256:2bfc36bfccbe047671170ea5677efd3d5ab730a55d7e45611d76d495e5b96766 \ + --hash=sha256:32e82d5a640febc688c0789e15ea875bf696a10cf358f049e1ed841f01710a9b \ + --hash=sha256:3b2051bdc4bc3f02fa52483f6381cf40d4d48167645241993f9d7ebbd142ed9b \ + --hash=sha256:3f734bd8a08f5185a64fb6abb8f14dc97ec27a689ca808fb7a83cdd38d745e4f \ + --hash=sha256:3f78dd8de3112df8bbd970f0916ac876dc3fbe63810bd1cf7cc5eec4cbac4f04 \ + --hash=sha256:4eabeb48508953ba1f3590ad0773b8daea9e104eec66d661917e9bbcd7125a67 \ + --hash=sha256:4f05ecc33808187f430f249cb1ccab35c38f570b181f2d380fbe253da94b18d8 \ + --hash=sha256:4f4f4cbf23d3afc1526294a31e7b3eaa0f682cc28ac5366065dc1d6bb18bd7be \ + --hash=sha256:5483d5e70aacd06f0aa3effec9fed597c0b50f45060956eeeb1203c44d4338c3 \ + --hash=sha256:56a5f9b46892b115a75d0a1f2292431ad5988461175826600acc69a24cb3edee \ + --hash=sha256:64bb63af8a06f736927d260efdd4dfc5253d42244f281a8063e4b9eea2ddcbc5 \ + --hash=sha256:653f8cbefcf7c6ac4cece2cdef367c4faa2b7c19795d52bd7cbec11a8739a7c1 \ + --hash=sha256:664211d63306e4bd4eec35bf2b4bd9db61c394037911cf2d1804c43b511a49f1 \ + --hash=sha256:6651e6caed66a8fff0fef1a3e81c0ed2253bf361c0fdc834500488732c5d16e9 \ + --hash=sha256:6c1fba6cdfdf105739d3069cf7b07664f2944d82a8098218ab2300a82d8f40fc \ + --hash=sha256:6e64246e6e9044a4534a69dca1283c6ddab6e757be5e6874f69024329b3aa61f \ + --hash=sha256:838390245c7ec137af4993c0c8052f49d5ec79e422b4451bfa37fee9b9ccaa01 \ + --hash=sha256:856b410a14793069d8ba35f33fff667213ea66f2df25a0024cc72a7493c56d4c \ + --hash=sha256:8b932c364c1d1605a91907a41128ed0ee8a2d326fc0fafb2c55cd46f545f4599 \ + --hash=sha256:9086cf6d20f08dae7f296a78f6c77d1f8d24079d448f023ee0eb329078dd35e1 \ + --hash=sha256:9698533c14afa0548188de4968a7932d1f3f965f3f5ba1474de673596bb875af \ + --hash=sha256:9b12b05dd7c28f5068387c1afee8cb94f9d02501e7ef495a7c5c7e27139b96ad \ + --hash=sha256:a884c7426a5bc6fb7fc71a55ad14e66818e13f05b78b20a6f37175f324b7acb8 \ + --hash=sha256:abe9e7f1a3e76286c5f5baf2bf5162d41dc0310da493b34a2c36555f38d928f7 \ + --hash=sha256:bd6fde63b015a27262be06bd6bbdd895273cc2bdf2d4c7e1c83711d26a8fbace \ + --hash=sha256:bda7c62c954f47b87ed9a89f525eee1b318ec7c2162dfdba76c2ccfa334e0caa \ + --hash=sha256:be8a4908dd3f6e965993c0068b006bdbd0474fbcbd1da4893b49356e73fc1557 \ + --hash=sha256:ced65fc3c7d7205267506d854bb1815bb445899cca9d21d1d4b949070a635546 \ + --hash=sha256:dac4279aa05055d3897ab5e5ee5a7b39db121f91df65a530f8b1ac7f9bd93119 \ + --hash=sha256:e4f1863056e3e4f399c285b67fa816f411a7bfa1c81ef50e186126164e396e59 \ + --hash=sha256:ecd85f68b8cd9ab78a0141e87ea9a53b2f31fd9b1350a1c44da1f7481b5363ef \ + --hash=sha256:ed269b83750413e8fc5c96276372f49ee3fcb7ed61c49fe8e5a67f54459a5a4a \ + --hash=sha256:f19b0b80cba73b204dee68501870b11067711d21d243fb6774256d3ca2e5391f \ + --hash=sha256:ffdafb98db7574f9da84c489a10a5d582079a888cb43c64e9e6b0e3fe1034685 # Contains the requirements for the letsencrypt package. # @@ -1338,18 +1503,18 @@ letsencrypt==0.7.0 \ --hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \ --hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9 -certbot==0.40.1 \ - --hash=sha256:afe4d7edc61d4cab8b6f7ab7611d66aaba67d9f0404fa2760bd1cc430b2ec9ec \ - --hash=sha256:8dc81b3044cf401c55fa36c30893887fcb92657df1d76a8848059683df3b10d1 -acme==0.40.1 \ - --hash=sha256:a85387c26fb4fc24511b2579b8c61177b3175fd25e130c5be95a840d9f67d54f \ - --hash=sha256:33bf8686408d5b6b79886a9a43aee691ca754408deaec4fb2bb17b9af48a5ffc -certbot-apache==0.40.1 \ - --hash=sha256:6c4a4e21a17bd8120056595e5670c9a0f86756da0ad269196e8d56fc1b9fec82 \ - --hash=sha256:16404e9e404f0b98c18bd752fad812a45ef7f9b0efa9bbc8589f24a94e67de7c -certbot-nginx==0.40.1 \ - --hash=sha256:acdbfc4ab75ebc810264ee1248332f8e857c5e7776717b7cd53c4ceceb2b4d34 \ - --hash=sha256:014fdda80647ad9e67019b16c7cdaee5d21a750b393bcb98e1300615cc930f4f +certbot==1.1.0 \ + --hash=sha256:66a5cab9267349941604c2c98082bfef85877653c023fc324b1c3869fb16add6 \ + --hash=sha256:46e93661a0db53f416c0f5476d8d2e62bc7259b7660dd983453b85df9ef6e8b8 +acme==1.1.0 \ + --hash=sha256:11b9beba706fb8f652c8910d46dd1939d670cac8169f3c66c18c080ed3353e71 \ + --hash=sha256:c305a20eeb9cb02240347703d497891c13d43a47c794fa100d4dbb479a5370d9 +certbot-apache==1.1.0 \ + --hash=sha256:9c847ff223c2e465e241c78d22f97cee77d5e551df608bed06c55f8627f4cbd2 \ + --hash=sha256:05e84dfe96b72582cde97c490977d8e2d33d440c927a320debb4cf287f6fadcc +certbot-nginx==1.1.0 \ + --hash=sha256:bf06fa2f5059f0fdb7d352c8739e1ed0830db4f0d89e812dab4f081bda6ec7d6 \ + --hash=sha256:0a80ecbd2a30f3757c7652cabfff854ca07873b1cf02ebbe1892786c3b3a5874 UNLIKELY_EOF # ------------------------------------------------------------------------- @@ -1583,6 +1748,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 @@ -1794,30 +1962,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 "$@" diff --git a/letsencrypt-auto-source/letsencrypt-auto.sig b/letsencrypt-auto-source/letsencrypt-auto.sig index ce698e84d..bae77d59b 100644 Binary files a/letsencrypt-auto-source/letsencrypt-auto.sig and b/letsencrypt-auto-source/letsencrypt-auto.sig differ diff --git a/letsencrypt-auto-source/letsencrypt-auto.template b/letsencrypt-auto-source/letsencrypt-auto.template index 31c5bb134..53e57a498 100755 --- a/letsencrypt-auto-source/letsencrypt-auto.template +++ b/letsencrypt-auto-source/letsencrypt-auto.template @@ -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..." @@ -298,6 +306,7 @@ DeterminePythonVersion() { {{ bootstrappers/deb_common.sh }} {{ bootstrappers/rpm_common_base.sh }} {{ bootstrappers/rpm_common.sh }} +{{ bootstrappers/rpm_python3_legacy.sh }} {{ bootstrappers/rpm_python3.sh }} {{ bootstrappers/suse_common.sh }} {{ bootstrappers/arch_common.sh }} @@ -333,6 +342,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". @@ -344,31 +358,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" @@ -445,6 +478,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. @@ -534,6 +574,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 @@ -545,8 +607,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 @@ -557,12 +626,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 @@ -657,6 +735,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 @@ -720,30 +801,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 "$@" diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common_base.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common_base.sh index 326ad8b3f..2b00b199b 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/rpm_common_base.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/rpm_common_base.sh @@ -3,7 +3,9 @@ # 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 @@ -23,26 +25,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() { diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3.sh index f33b07ca9..ac0553db5 100644 --- a/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3.sh +++ b/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3.sh @@ -4,7 +4,6 @@ BOOTSTRAP_RPM_PYTHON3_VERSION=1 BootstrapRpmPython3() { # Tested with: - # - CentOS 6 # - Fedora 29 InitializeRPMCommonBase @@ -15,12 +14,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 diff --git a/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh b/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh new file mode 100644 index 000000000..febfc7a83 --- /dev/null +++ b/letsencrypt-auto-source/pieces/bootstrappers/rpm_python3_legacy.sh @@ -0,0 +1,78 @@ +# 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 +} diff --git a/letsencrypt-auto-source/pieces/certbot-requirements.txt b/letsencrypt-auto-source/pieces/certbot-requirements.txt index 5029feb9d..67a33390b 100644 --- a/letsencrypt-auto-source/pieces/certbot-requirements.txt +++ b/letsencrypt-auto-source/pieces/certbot-requirements.txt @@ -1,12 +1,12 @@ -certbot==0.40.1 \ - --hash=sha256:afe4d7edc61d4cab8b6f7ab7611d66aaba67d9f0404fa2760bd1cc430b2ec9ec \ - --hash=sha256:8dc81b3044cf401c55fa36c30893887fcb92657df1d76a8848059683df3b10d1 -acme==0.40.1 \ - --hash=sha256:a85387c26fb4fc24511b2579b8c61177b3175fd25e130c5be95a840d9f67d54f \ - --hash=sha256:33bf8686408d5b6b79886a9a43aee691ca754408deaec4fb2bb17b9af48a5ffc -certbot-apache==0.40.1 \ - --hash=sha256:6c4a4e21a17bd8120056595e5670c9a0f86756da0ad269196e8d56fc1b9fec82 \ - --hash=sha256:16404e9e404f0b98c18bd752fad812a45ef7f9b0efa9bbc8589f24a94e67de7c -certbot-nginx==0.40.1 \ - --hash=sha256:acdbfc4ab75ebc810264ee1248332f8e857c5e7776717b7cd53c4ceceb2b4d34 \ - --hash=sha256:014fdda80647ad9e67019b16c7cdaee5d21a750b393bcb98e1300615cc930f4f +certbot==1.1.0 \ + --hash=sha256:66a5cab9267349941604c2c98082bfef85877653c023fc324b1c3869fb16add6 \ + --hash=sha256:46e93661a0db53f416c0f5476d8d2e62bc7259b7660dd983453b85df9ef6e8b8 +acme==1.1.0 \ + --hash=sha256:11b9beba706fb8f652c8910d46dd1939d670cac8169f3c66c18c080ed3353e71 \ + --hash=sha256:c305a20eeb9cb02240347703d497891c13d43a47c794fa100d4dbb479a5370d9 +certbot-apache==1.1.0 \ + --hash=sha256:9c847ff223c2e465e241c78d22f97cee77d5e551df608bed06c55f8627f4cbd2 \ + --hash=sha256:05e84dfe96b72582cde97c490977d8e2d33d440c927a320debb4cf287f6fadcc +certbot-nginx==1.1.0 \ + --hash=sha256:bf06fa2f5059f0fdb7d352c8739e1ed0830db4f0d89e812dab4f081bda6ec7d6 \ + --hash=sha256:0a80ecbd2a30f3757c7652cabfff854ca07873b1cf02ebbe1892786c3b3a5874 diff --git a/letsencrypt-auto-source/pieces/dependency-requirements.txt b/letsencrypt-auto-source/pieces/dependency-requirements.txt index 2d683eb48..034fae46d 100644 --- a/letsencrypt-auto-source/pieces/dependency-requirements.txt +++ b/letsencrypt-auto-source/pieces/dependency-requirements.txt @@ -11,63 +11,70 @@ # ``` ConfigArgParse==0.14.0 \ --hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91 -asn1crypto==0.24.0 \ - --hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \ - --hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49 -certifi==2019.6.16 \ - --hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \ - --hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695 -cffi==1.12.3 \ - --hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \ - --hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \ - --hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \ - --hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \ - --hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \ - --hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \ - --hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \ - --hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \ - --hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \ - --hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \ - --hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \ - --hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \ - --hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \ - --hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \ - --hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \ - --hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \ - --hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \ - --hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \ - --hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \ - --hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \ - --hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \ - --hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \ - --hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \ - --hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \ - --hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \ - --hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \ - --hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \ - --hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201 +certifi==2019.9.11 \ + --hash=sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50 \ + --hash=sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef +cffi==1.13.2 \ + --hash=sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42 \ + --hash=sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04 \ + --hash=sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5 \ + --hash=sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54 \ + --hash=sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba \ + --hash=sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57 \ + --hash=sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396 \ + --hash=sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12 \ + --hash=sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97 \ + --hash=sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43 \ + --hash=sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db \ + --hash=sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3 \ + --hash=sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b \ + --hash=sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579 \ + --hash=sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346 \ + --hash=sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159 \ + --hash=sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652 \ + --hash=sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e \ + --hash=sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a \ + --hash=sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506 \ + --hash=sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f \ + --hash=sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d \ + --hash=sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c \ + --hash=sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20 \ + --hash=sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858 \ + --hash=sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc \ + --hash=sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a \ + --hash=sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3 \ + --hash=sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e \ + --hash=sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410 \ + --hash=sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25 \ + --hash=sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b \ + --hash=sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d chardet==3.0.4 \ --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \ --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 configobj==5.0.6 \ --hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902 -cryptography==2.7 \ - --hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \ - --hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \ - --hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \ - --hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \ - --hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \ - --hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \ - --hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \ - --hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \ - --hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \ - --hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \ - --hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \ - --hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \ - --hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \ - --hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \ - --hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \ - --hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d +cryptography==2.8 \ + --hash=sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c \ + --hash=sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595 \ + --hash=sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad \ + --hash=sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651 \ + --hash=sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2 \ + --hash=sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff \ + --hash=sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d \ + --hash=sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42 \ + --hash=sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d \ + --hash=sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e \ + --hash=sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912 \ + --hash=sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793 \ + --hash=sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13 \ + --hash=sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7 \ + --hash=sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0 \ + --hash=sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879 \ + --hash=sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f \ + --hash=sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9 \ + --hash=sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2 \ + --hash=sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf \ + --hash=sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8 distro==1.4.0 \ --hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \ --hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4 @@ -79,14 +86,14 @@ enum34==1.1.6 \ funcsigs==1.0.2 \ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \ --hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50 -future==0.17.1 \ - --hash=sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8 +future==0.18.2 \ + --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d idna==2.8 \ --hash=sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407 \ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c -ipaddress==1.0.22 \ - --hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \ - --hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c +ipaddress==1.0.23 \ + --hash=sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc \ + --hash=sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2 josepy==1.2.0 \ --hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \ --hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3 @@ -96,9 +103,9 @@ mock==1.3.0 \ parsedatetime==2.4 \ --hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \ --hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094 -pbr==5.4.2 \ - --hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \ - --hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf +pbr==5.4.3 \ + --hash=sha256:2c8e420cd4ed4cec4e7999ee47409e876af575d4c35a45840d59e8b5f3155ab8 \ + --hash=sha256:b32c8ccaac7b1a20c0ce00ce317642e6cf231cf038f9875e0280e28af5bf7ac9 pyOpenSSL==19.0.0 \ --hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \ --hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6 @@ -107,29 +114,28 @@ pyRFC3339==1.1 \ --hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a pycparser==2.19 \ --hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3 -pyparsing==2.4.2 \ - --hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \ - --hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4 +pyparsing==2.4.5 \ + --hash=sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f \ + --hash=sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a python-augeas==0.5.0 \ --hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2 -pytz==2019.2 \ - --hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \ - --hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7 +pytz==2019.3 \ + --hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \ + --hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be requests==2.21.0 \ --hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \ --hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b requests-toolbelt==0.9.1 \ --hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \ --hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0 -six==1.12.0 \ - --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \ - --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 +six==1.13.0 \ + --hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \ + --hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66 urllib3==1.24.3 \ --hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \ --hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb -zope.component==4.5 \ - --hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \ - --hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4 +zope.component==4.6 \ + --hash=sha256:ec2afc5bbe611dcace98bb39822c122d44743d635dafc7315b9aef25097db9e6 zope.deferredimport==4.3.1 \ --hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \ --hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a @@ -180,15 +186,43 @@ zope.interface==4.6.0 \ --hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \ --hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \ --hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317 -zope.proxy==4.3.2 \ - --hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \ - --hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \ - --hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \ - --hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \ - --hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \ - --hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \ - --hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \ - --hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \ - --hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \ - --hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \ - --hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366 +zope.proxy==4.3.3 \ + --hash=sha256:04646ac04ffa9c8e32fb2b5c3cd42995b2548ea14251f3c21ca704afae88e42c \ + --hash=sha256:07b6bceea232559d24358832f1cd2ed344bbf05ca83855a5b9698b5f23c5ed60 \ + --hash=sha256:1ef452cc02e0e2f8e3c917b1a5b936ef3280f2c2ca854ee70ac2164d1655f7e6 \ + --hash=sha256:22bf61857c5977f34d4e391476d40f9a3b8c6ab24fb0cac448d42d8f8b9bf7b2 \ + --hash=sha256:299870e3428cbff1cd9f9b34144e76ecdc1d9e3192a8cf5f1b0258f47a239f58 \ + --hash=sha256:2bfc36bfccbe047671170ea5677efd3d5ab730a55d7e45611d76d495e5b96766 \ + --hash=sha256:32e82d5a640febc688c0789e15ea875bf696a10cf358f049e1ed841f01710a9b \ + --hash=sha256:3b2051bdc4bc3f02fa52483f6381cf40d4d48167645241993f9d7ebbd142ed9b \ + --hash=sha256:3f734bd8a08f5185a64fb6abb8f14dc97ec27a689ca808fb7a83cdd38d745e4f \ + --hash=sha256:3f78dd8de3112df8bbd970f0916ac876dc3fbe63810bd1cf7cc5eec4cbac4f04 \ + --hash=sha256:4eabeb48508953ba1f3590ad0773b8daea9e104eec66d661917e9bbcd7125a67 \ + --hash=sha256:4f05ecc33808187f430f249cb1ccab35c38f570b181f2d380fbe253da94b18d8 \ + --hash=sha256:4f4f4cbf23d3afc1526294a31e7b3eaa0f682cc28ac5366065dc1d6bb18bd7be \ + --hash=sha256:5483d5e70aacd06f0aa3effec9fed597c0b50f45060956eeeb1203c44d4338c3 \ + --hash=sha256:56a5f9b46892b115a75d0a1f2292431ad5988461175826600acc69a24cb3edee \ + --hash=sha256:64bb63af8a06f736927d260efdd4dfc5253d42244f281a8063e4b9eea2ddcbc5 \ + --hash=sha256:653f8cbefcf7c6ac4cece2cdef367c4faa2b7c19795d52bd7cbec11a8739a7c1 \ + --hash=sha256:664211d63306e4bd4eec35bf2b4bd9db61c394037911cf2d1804c43b511a49f1 \ + --hash=sha256:6651e6caed66a8fff0fef1a3e81c0ed2253bf361c0fdc834500488732c5d16e9 \ + --hash=sha256:6c1fba6cdfdf105739d3069cf7b07664f2944d82a8098218ab2300a82d8f40fc \ + --hash=sha256:6e64246e6e9044a4534a69dca1283c6ddab6e757be5e6874f69024329b3aa61f \ + --hash=sha256:838390245c7ec137af4993c0c8052f49d5ec79e422b4451bfa37fee9b9ccaa01 \ + --hash=sha256:856b410a14793069d8ba35f33fff667213ea66f2df25a0024cc72a7493c56d4c \ + --hash=sha256:8b932c364c1d1605a91907a41128ed0ee8a2d326fc0fafb2c55cd46f545f4599 \ + --hash=sha256:9086cf6d20f08dae7f296a78f6c77d1f8d24079d448f023ee0eb329078dd35e1 \ + --hash=sha256:9698533c14afa0548188de4968a7932d1f3f965f3f5ba1474de673596bb875af \ + --hash=sha256:9b12b05dd7c28f5068387c1afee8cb94f9d02501e7ef495a7c5c7e27139b96ad \ + --hash=sha256:a884c7426a5bc6fb7fc71a55ad14e66818e13f05b78b20a6f37175f324b7acb8 \ + --hash=sha256:abe9e7f1a3e76286c5f5baf2bf5162d41dc0310da493b34a2c36555f38d928f7 \ + --hash=sha256:bd6fde63b015a27262be06bd6bbdd895273cc2bdf2d4c7e1c83711d26a8fbace \ + --hash=sha256:bda7c62c954f47b87ed9a89f525eee1b318ec7c2162dfdba76c2ccfa334e0caa \ + --hash=sha256:be8a4908dd3f6e965993c0068b006bdbd0474fbcbd1da4893b49356e73fc1557 \ + --hash=sha256:ced65fc3c7d7205267506d854bb1815bb445899cca9d21d1d4b949070a635546 \ + --hash=sha256:dac4279aa05055d3897ab5e5ee5a7b39db121f91df65a530f8b1ac7f9bd93119 \ + --hash=sha256:e4f1863056e3e4f399c285b67fa816f411a7bfa1c81ef50e186126164e396e59 \ + --hash=sha256:ecd85f68b8cd9ab78a0141e87ea9a53b2f31fd9b1350a1c44da1f7481b5363ef \ + --hash=sha256:ed269b83750413e8fc5c96276372f49ee3fcb7ed61c49fe8e5a67f54459a5a4a \ + --hash=sha256:f19b0b80cba73b204dee68501870b11067711d21d243fb6774256d3ca2e5391f \ + --hash=sha256:ffdafb98db7574f9da84c489a10a5d582079a888cb43c64e9e6b0e3fe1034685 diff --git a/letsencrypt-auto-source/rebuild_dependencies.py b/letsencrypt-auto-source/rebuild_dependencies.py index 0db787a0b..a79bdd8aa 100755 --- a/letsencrypt-auto-source/rebuild_dependencies.py +++ b/letsencrypt-auto-source/rebuild_dependencies.py @@ -46,9 +46,12 @@ AUTHORITATIVE_CONSTRAINTS = { # certbot-auto failures on Python 3.6+ which enum34 doesn't support. See #5456. # TODO: hashin seems to overwrite environment markers in dependencies. This needs to be fixed. 'enum34': '1.1.6 ; python_version < \'3.4\'', - # Newer versions of requests dropped support for python 3.4. Once Certbot does as well, - # we should unpin the dependency. + # Newer versions of the packages below dropped support for python 3.4. Once + # Certbot does as well, we should unpin these dependencies. 'requests': '2.21.0', + 'ConfigArgParse': '0.14.0', + 'zope.hookable': '4.2.0', + 'zope.interface': '4.6.0', } @@ -62,8 +65,7 @@ CERTBOT_REPO_PATH = dirname(dirname(abspath(__file__))) # without pinned dependencies, and respecting input authoritative requirements # - `certbot plugins` is called to check we have an healthy environment # - finally current set of dependencies is extracted out of the docker using pip freeze -SCRIPT = r"""\ -#!/bin/sh +SCRIPT = r"""#!/bin/sh set -e cd /tmp/certbot @@ -73,7 +75,7 @@ PYVER=`/opt/eff.org/certbot/venv/bin/python --version 2>&1 | cut -d" " -f 2 | cu /opt/eff.org/certbot/venv/bin/python letsencrypt-auto-source/pieces/create_venv.py /tmp/venv "$PYVER" 1 /tmp/venv/bin/python letsencrypt-auto-source/pieces/pipstrap.py -/tmp/venv/bin/pip install -e acme -e . -e certbot-apache -e certbot-nginx -c /tmp/constraints.txt +/tmp/venv/bin/pip install -e acme -e certbot -e certbot-apache -e certbot-nginx -c /tmp/constraints.txt /tmp/venv/bin/certbot plugins /tmp/venv/bin/pip freeze >> /tmp/workspace/requirements.txt """ diff --git a/letsencrypt-auto-source/tests/centos6_tests.sh b/letsencrypt-auto-source/tests/centos6_tests.sh index 2c6dcf734..86b307ad2 100644 --- a/letsencrypt-auto-source/tests/centos6_tests.sh +++ b/letsencrypt-auto-source/tests/centos6_tests.sh @@ -1,81 +1,173 @@ #!/bin/bash +set -e # Start by making sure your system is up-to-date: -yum update -y > /dev/null -yum install -y centos-release-scl > /dev/null -yum install -y python27 > /dev/null 2> /dev/null +yum update -y >/dev/null +yum install -y centos-release-scl >/dev/null +yum install -y python27 >/dev/null 2>/dev/null +LE_AUTO_PY_34="certbot/letsencrypt-auto-source/letsencrypt-auto_py_34" LE_AUTO="certbot/letsencrypt-auto-source/letsencrypt-auto" +# Last version of certbot-auto that was bootstraping Python 3.4 for CentOS 6 users +INITIAL_CERTBOT_VERSION_PY34="certbot 0.38.0" + # we're going to modify env variables, so do this in a subshell ( -source /opt/rh/python27/enable - -# ensure python 3 isn't installed -python3 --version 2> /dev/null -RESULT=$? -if [ $RESULT -eq 0 ]; then - error "Python3 is already installed." +# ensure CentOS6 32bits is not supported anymore, and so certbot is not installed +export UNAME_FAKE_32BITS=true +if ! "$LE_AUTO" 2>&1 | grep -q "Certbot cannot be installed."; then + echo "ERROR: certbot-auto installed certbot on 32-bit CentOS." exit 1 fi +) -# ensure python2.7 is available -python2.7 --version 2> /dev/null -RESULT=$? -if [ $RESULT -ne 0 ]; then - error "Python3 is not available." - exit 1 -fi +echo "PASSED: On CentOS 6 32 bits, certbot-auto refused to install certbot." -# bootstrap, but don't install python 3. -"$LE_AUTO" --no-self-upgrade -n > /dev/null 2> /dev/null +# we're going to modify env variables, so do this in a subshell +( + . /opt/rh/python27/enable -# ensure python 3 isn't installed -python3 --version 2> /dev/null -RESULT=$? -if [ $RESULT -eq 0 ]; then - error "letsencrypt-auto installed Python3 even though Python2.7 is present." - exit 1 -fi + # ensure python 3 isn't installed + if python3 --version 2> /dev/null; then + echo "ERROR: Python3 is already installed." + exit 1 + fi -echo "" -echo "PASSED: Did not upgrade to Python3 when Python2.7 is present." + # ensure python2.7 is available + if ! python2.7 --version 2> /dev/null; then + echo "ERROR: Python2.7 is not available." + exit 1 + fi + + # bootstrap, but don't install python 3. + "$LE_AUTO" --no-self-upgrade -n --version > /dev/null 2> /dev/null + + # ensure python 3 isn't installed + if python3 --version 2> /dev/null; then + echo "ERROR: letsencrypt-auto installed Python3 even though Python2.7 is present." + exit 1 + fi + + echo "PASSED: Did not upgrade to Python3 when Python2.7 is present." ) # ensure python2.7 isn't available -python2.7 --version 2> /dev/null -RESULT=$? -if [ $RESULT -eq 0 ]; then - error "Python2.7 is still available." +if python2.7 --version 2> /dev/null; then + echo "ERROR: Python2.7 is still available." exit 1 fi # Skip self upgrade due to Python 3 not being available. if ! "$LE_AUTO" 2>&1 | grep -q "WARNING: couldn't find Python"; then - echo "Python upgrade failure warning not printed!" + echo "ERROR: Python upgrade failure warning not printed!" exit 1 fi -# bootstrap, this time installing python3 -"$LE_AUTO" --no-self-upgrade -n > /dev/null 2> /dev/null +# bootstrap from the old letsencrypt-auto, this time installing python3.4 +"$LE_AUTO_PY_34" --no-self-upgrade -n --version >/dev/null 2>/dev/null -# ensure python 3 is installed -python3 --version > /dev/null -RESULT=$? -if [ $RESULT -ne 0 ]; then - error "letsencrypt-auto failed to install Python3 when only Python2.6 is present." +# ensure python 3.4 is installed +if ! python3.4 --version >/dev/null 2>/dev/null; then + echo "ERROR: letsencrypt-auto failed to install Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present." exit 1 fi -echo "PASSED: Successfully upgraded to Python3 when only Python2.6 is present." -echo "" +echo "PASSED: Successfully upgraded to Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present." -export VENV_PATH=$(mktemp -d) -"$LE_AUTO" -n --no-bootstrap --no-self-upgrade --version >/dev/null 2>&1 -if [ "$($VENV_PATH/bin/python -V 2>&1 | cut -d" " -f2 | cut -d. -f1)" != 3 ]; then - echo "Python 3 wasn't used with --no-bootstrap!" +# As "certbot-auto" (so without implicit --non-interactive flag set), check that the script +# refuses to install SCL Python 3.6 when run in a non interactive shell (simulated here +# using | tee /dev/null) if --non-interactive flag is not provided. +cp "$LE_AUTO" /tmp/certbot-auto +# NB: Readline has an issue on all Python versions for CentOS 6, making `certbot --version` +# output an unprintable ASCII character on a new line at the end. +# So we take the second last line of the output. +version=$(/tmp/certbot-auto --version 2>/dev/null | tee /dev/null | tail -2 | head -1) + +if [ "$version" != "$INITIAL_CERTBOT_VERSION_PY34" ]; then + echo "ERROR: certbot-auto upgraded certbot in a non-interactive shell with --non-interactive flag not set." exit 1 fi -unset VENV_PATH + +echo "PASSED: certbot-auto did not upgrade certbot in a non-interactive shell with --non-interactive flag not set." + +if [ -f /opt/rh/rh-python36/enable ]; then + echo "ERROR: certbot-auto installed Python3.6 in a non-interactive shell with --non-interactive flag not set." + exit 1 +fi + +echo "PASSED: certbot-auto did not install Python3.6 in a non-interactive shell with --non-interactive flag not set." + +# now bootstrap from current letsencrypt-auto, that will install python3.6 from SCL +"$LE_AUTO" --no-self-upgrade -n --version >/dev/null 2>/dev/null + +# Following test is exectued in a subshell, to not leak any environment variable +( + # enable SCL rh-python36 + . /opt/rh/rh-python36/enable + + # ensure python 3.6 is installed + if ! python3.6 --version >/dev/null 2>/dev/null; then + echo "ERROR: letsencrypt-auto failed to install Python3.6 using current letsencrypt-auto when only Python2.6/Python3.4 are present." + exit 1 + fi + + echo "PASSED: Successfully upgraded to Python3.6 using current letsencrypt-auto when only Python2.6/Python3.4 are present." +) + +# Following test is executed in a subshell, to not leak any environment variable +( + export VENV_PATH=$(mktemp -d) + "$LE_AUTO" -n --no-bootstrap --no-self-upgrade --version >/dev/null 2>&1 + if [ "$($VENV_PATH/bin/python -V 2>&1 | cut -d" " -f2 | cut -d. -f1-2)" != "3.6" ]; then + echo "ERROR: Python 3.6 wasn't used with --no-bootstrap!" + exit 1 + fi +) + +# Following test is exectued in a subshell, to not leak any environment variable +( + # enable SCL rh-python36 + . /opt/rh/rh-python36/enable + + # ensure everything works fine with certbot-auto bootstrap when python 3.6 is already enabled + export VENV_PATH=$(mktemp -d) + if ! "$LE_AUTO" --no-self-upgrade -n --version >/dev/null 2>/dev/null; then + echo "ERROR: Certbot-auto broke when Python 3.6 SCL is already enabled." + exit 1 + fi +) + +# we're going to modify env variables, so do this in a subshell +( + # ensure CentOS6 32bits is not supported anymore, and so certbot + # is not upgraded nor reinstalled. + export UNAME_FAKE_32BITS=true + OUTPUT=$("$LE_AUTO" --version 2>&1) + if ! echo "$OUTPUT" | grep -q "Certbot will no longer receive updates."; then + echo "ERROR: certbot-auto failed to run or upgraded pre-existing Certbot instance on 32-bit CentOS 6." + exit 1 + fi + if ! "$LE_AUTO" --install-only 2>&1 | grep -q "Certbot cannot be installed."; then + echo "ERROR: certbot-auto reinstalled Certbot on 32-bit CentOS 6." + exit 1 + fi +) + +# we're going to modify env variables, so do this in a subshell +( + # Prepare a certbot installation in the old venv path + rm -rf /opt/eff.org + VENV_PATH=~/.local/share/letsencrypt "$LE_AUTO" --install-only > /dev/null 2> /dev/null + # fake 32 bits mode + export UNAME_FAKE_32BITS=true + OUTPUT=$("$LE_AUTO" --version 2>&1) + if ! echo "$OUTPUT" | grep -q "Certbot will no longer receive updates."; then + echo "ERROR: certbot-auto failed to run or upgraded pre-existing Certbot instance in the old venv path on 32-bit CentOS 6." + exit 1 + fi +) + +echo "PASSED: certbot-auto refused to install/upgrade certbot on 32-bit CentOS 6." # test using python3 pytest -v -s certbot/letsencrypt-auto-source/tests diff --git a/letsencrypt-auto-source/tests/oraclelinux6_tests.sh b/letsencrypt-auto-source/tests/oraclelinux6_tests.sh new file mode 100644 index 000000000..f3fd952f3 --- /dev/null +++ b/letsencrypt-auto-source/tests/oraclelinux6_tests.sh @@ -0,0 +1,85 @@ +#!/bin/bash +set -eo pipefail +# Start by making sure your system is up-to-date: +yum update -y >/dev/null + +LE_AUTO_PY_34="certbot/letsencrypt-auto-source/letsencrypt-auto_py_34" +LE_AUTO="certbot/letsencrypt-auto-source/letsencrypt-auto" + +# Apply installation instructions from official documentation: +# https://certbot.eff.org/lets-encrypt/centosrhel6-other +cp "$LE_AUTO" /usr/local/bin/certbot-auto +chown root /usr/local/bin/certbot-auto +chmod 0755 /usr/local/bin/certbot-auto +LE_AUTO=/usr/local/bin/certbot-auto + +# Last version of certbot-auto that was bootstraping Python 3.4 for CentOS 6 users +INITIAL_CERTBOT_VERSION_PY34="certbot 0.38.0" + +# Check bootstrap from current certbot-auto will fail, because SCL is not enabled. +set +o pipefail +if ! "$LE_AUTO" -n 2>&1 | grep -q "Enable the SCL repository and try running Certbot again."; then + echo "ERROR: Bootstrap was not aborted although SCL was not installed!" + exit 1 +fi +set -o pipefail + +echo "PASSED: Bootstrap was aborted since SCL was not installed." + +# Bootstrap from the old letsencrypt-auto, Python 3.4 will be installed from EPEL. +"$LE_AUTO_PY_34" --no-self-upgrade -n --install-only >/dev/null 2>/dev/null + +# Ensure Python 3.4 is installed +if ! command -v python3.4 &>/dev/null; then + echo "ERROR: old letsencrypt-auto failed to install Python3.4 using letsencrypt-auto < 0.37.0 when only Python2.6 is present." + exit 1 +fi + +echo "PASSED: Bootstrap from old letsencrypt-auto succeeded and installed Python 3.4" + +# Expect certbot-auto to skip rebootstrapping with a warning since SCL is not installed. +if ! "$LE_AUTO" --non-interactive --version 2>&1 | grep -q "This requires manual user intervention"; then + echo "FAILED: Script certbot-auto did not print a warning about needing manual intervention!" + exit 1 +fi + +echo "PASSED: Script certbot-auto did not rebootstrap." + +# NB: Readline has an issue on all Python versions for OL 6, making `certbot --version` +# output an unprintable ASCII character on a new line at the end. +# So we take the second last line of the output. +version=$($LE_AUTO --version 2>/dev/null | tail -2 | head -1) + +if [ "$version" != "$INITIAL_CERTBOT_VERSION_PY34" ]; then + echo "ERROR: Script certbot-auto upgraded certbot in a non-interactive shell while SCL was not enabled." + exit 1 +fi + +echo "PASSED: Script certbot-auto did not upgrade certbot but started it successfully while SCL was not enabled." + +# Enable SCL +yum install -y oracle-softwarecollection-release-el6 >/dev/null + +# Expect certbot-auto to bootstrap successfully since SCL is available. +"$LE_AUTO" -n --version &>/dev/null + +if [ "$(/opt/eff.org/certbot/venv/bin/python -V 2>&1 | cut -d" " -f2 | cut -d. -f1-2)" != "3.6" ]; then + echo "ERROR: Script certbot-auto failed to bootstrap and install Python 3.6 while SCL is available." + exit 1 +fi + +if ! /opt/eff.org/certbot/venv/bin/certbot --version > /dev/null 2> /dev/null; then + echo "ERROR: Script certbot-auto did not install certbot correctly while SCL is enabled." + exit 1 +fi + +echo "PASSED: Script certbot-auto correctly bootstraped Certbot using rh-python36 when SCL is available." + +# Expect certbot-auto will be totally silent now that everything has been correctly boostraped. +OUTPUT_LEN=$("$LE_AUTO" --install-only --no-self-upgrade --quiet 2>&1 | wc -c) +if [ "$OUTPUT_LEN" != 0 ]; then + echo certbot-auto produced unexpected output! + exit 1 +fi + +echo "PASSED: Script certbot-auto did not print anything in quiet mode." diff --git a/letsencrypt-auto-source/tests/uname_wrapper.sh b/letsencrypt-auto-source/tests/uname_wrapper.sh new file mode 100644 index 000000000..df1f568c6 --- /dev/null +++ b/letsencrypt-auto-source/tests/uname_wrapper.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +uname_output=$(/bin/uname_orig "$@") + +if [ "$UNAME_FAKE_32BITS" = true ]; then + uname_output="${uname_output//x86_64/i686}" +fi + +echo "$uname_output" diff --git a/letsencrypt-auto-source/version.py b/letsencrypt-auto-source/version.py index c49d96654..d70ffefac 100755 --- a/letsencrypt-auto-source/version.py +++ b/letsencrypt-auto-source/version.py @@ -14,6 +14,7 @@ def certbot_version(build_script_dir): """Return the version number stamped in certbot/__init__.py.""" return re.search('''^__version__ = ['"](.+)['"].*''', file_contents(join(dirname(build_script_dir), + 'certbot', 'certbot', '__init__.py')), re.M).group(1) diff --git a/letshelp-certbot/docs/conf.py b/letshelp-certbot/docs/conf.py index 17d8b3ea9..fc482a348 100644 --- a/letshelp-certbot/docs/conf.py +++ b/letshelp-certbot/docs/conf.py @@ -12,10 +12,9 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys import os import shlex - +import sys here = os.path.abspath(os.path.dirname(__file__)) @@ -41,7 +40,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'] diff --git a/letshelp-certbot/letshelp_certbot/apache.py b/letshelp-certbot/letshelp_certbot/apache.py index 50f3c5ef6..ebe4e3671 100755 --- a/letshelp-certbot/letshelp_certbot/apache.py +++ b/letshelp-certbot/letshelp_certbot/apache.py @@ -74,7 +74,7 @@ def make_and_verify_selection(server_root, temp_dir): ans = six.moves.input("(Y)es/(N)o: ").lower() if ans.startswith("y"): return - elif ans.startswith("n"): + if ans.startswith("n"): sys.exit("Your files were not submitted") @@ -159,7 +159,7 @@ def safe_config_file(config_file): empty_or_all_comments = False if line.startswith("-----BEGIN"): return False - elif ":" not in line: + if ":" not in line: possible_password_file = False # If file isn't empty or commented out and could be a password file, # don't include it in selection. It is safe to include the file if diff --git a/letshelp-certbot/letshelp_certbot/apache_test.py b/letshelp-certbot/letshelp_certbot/apache_test.py index a84641bfe..0853046b4 100644 --- a/letshelp-certbot/letshelp_certbot/apache_test.py +++ b/letshelp-certbot/letshelp_certbot/apache_test.py @@ -6,15 +6,14 @@ import subprocess import tarfile import tempfile import unittest -import pkg_resources -import mock # six is used in mock.patch() +import mock +import pkg_resources import six # pylint: disable=unused-import import letshelp_certbot.apache as letshelp_le_apache - _PARTIAL_CONF_PATH = os.path.join("mods-available", "ssl.load") _PARTIAL_LINK_PATH = os.path.join("mods-enabled", "ssl.load") _CONFIG_FILE = pkg_resources.resource_filename( diff --git a/letshelp-certbot/letshelp_certbot/magic_typing.py b/letshelp-certbot/letshelp_certbot/magic_typing.py index 471b8dfa9..5a6358c69 100644 --- a/letshelp-certbot/letshelp_certbot/magic_typing.py +++ b/letshelp-certbot/letshelp_certbot/magic_typing.py @@ -1,6 +1,7 @@ """Shim class to not have to depend on typing module in prod.""" import sys + class TypingClass(object): """Ignore import errors by getting anything""" def __getattr__(self, name): diff --git a/letshelp-certbot/readthedocs.org.requirements.txt b/letshelp-certbot/readthedocs.org.requirements.txt index 7858b312f..b24681caa 100644 --- a/letshelp-certbot/readthedocs.org.requirements.txt +++ b/letshelp-certbot/readthedocs.org.requirements.txt @@ -1,10 +1,10 @@ # readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation +# install -e certbot[docs]" (that would in turn install documentation # dependencies), but it allows to specify a requirements.txt file at # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) # Although ReadTheDocs certainly doesn't need to install the project # in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead +# expected and "pip install -e certbot[docs]" must be used instead -e letshelp-certbot[docs] diff --git a/letshelp-certbot/setup.py b/letshelp-certbot/setup.py index cb5171b72..af992de16 100644 --- a/letshelp-certbot/setup.py +++ b/letshelp-certbot/setup.py @@ -1,6 +1,5 @@ -from setuptools import setup from setuptools import find_packages - +from setuptools import setup version = '0.7.0.dev0' diff --git a/linter_plugin.py b/linter_plugin.py index e870fda3a..6be8c2414 100644 --- a/linter_plugin.py +++ b/linter_plugin.py @@ -1,13 +1,14 @@ -"""Certbot PyLint plugin. -http://docs.pylint.org/plugins.html """ -# The built-in ImportChecker of Pylint does a similar job to ForbidStandardOsModule to detect -# deprecated modules. You can check its behavior as a reference to what is coded here. -# See https://github.com/PyCQA/pylint/blob/b20a2984c94e2946669d727dbda78735882bf50a/pylint/checkers/imports.py#L287 +Certbot PyLint plugin. + +The built-in ImportChecker of Pylint does a similar job to ForbidStandardOsModule to detect +deprecated modules. You can check its behavior as a reference to what is coded here. +See https://github.com/PyCQA/pylint/blob/b20a2984c94e2946669d727dbda78735882bf50a/pylint/checkers/imports.py#L287 +See http://docs.pylint.org/plugins.html +""" from pylint.checkers import BaseChecker from pylint.interfaces import IAstroidChecker - # Modules in theses packages can import the os module. WHITELIST_PACKAGES = ['acme', 'certbot_compatibility_test', 'letshelp_certbot', 'lock_test'] diff --git a/pull_request_template.md b/pull_request_template.md index 9bf8f3f2d..c806d33e8 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -1,10 +1,4 @@ ## Pull Request Checklist -- [ ] If the change being made is to a [distributed - component](https://certbot.eff.org/docs/contributing.html#code-components-and-layout), - edit the `master` section of `CHANGELOG.md` to include a description of the - change being made. -- [ ] Add [mypy type - annotations](https://certbot.eff.org/docs/contributing.html#mypy-type-annotations) - for any functions that were added or modified. +- [ ] If the change being made is to a [distributed component](https://certbot.eff.org/docs/contributing.html#code-components-and-layout), edit the `master` section of `certbot/CHANGELOG.md` to include a description of the change being made. - [ ] Include your name in `AUTHORS.md` if you like. diff --git a/readthedocs.org.requirements.txt b/readthedocs.org.requirements.txt deleted file mode 100644 index 94a81e788..000000000 --- a/readthedocs.org.requirements.txt +++ /dev/null @@ -1,11 +0,0 @@ -# readthedocs.org gives no way to change the install command to "pip -# install -e .[docs]" (that would in turn install documentation -# dependencies), but it allows to specify a requirements.txt file at -# https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) - -# Although ReadTheDocs certainly doesn't need to install the project -# in --editable mode (-e), just "pip install .[docs]" does not work as -# expected and "pip install -e .[docs]" must be used instead - --e acme --e .[docs] diff --git a/tests/letstest/multitester.py b/tests/letstest/multitester.py index cfa53df7e..9ea9fe76b 100644 --- a/tests/letstest/multitester.py +++ b/tests/letstest/multitester.py @@ -32,17 +32,31 @@ see: from __future__ import print_function from __future__ import with_statement -import sys, os, time, argparse, socket, traceback +import argparse import multiprocessing as mp from multiprocessing import Manager +import os +import socket +import sys +import time +import traceback import urllib2 -import yaml + import boto3 from botocore.exceptions import ClientError +import yaml + import fabric -from fabric.api import run, execute, local, env, sudo, cd, lcd -from fabric.operations import get, put +from fabric.api import cd +from fabric.api import env +from fabric.api import execute +from fabric.api import lcd +from fabric.api import local +from fabric.api import run +from fabric.api import sudo from fabric.context_managers import shell_env +from fabric.operations import get +from fabric.operations import put # Command line parser #------------------------------------------------------------------------------- diff --git a/tests/letstest/scripts/test_apache2.sh b/tests/letstest/scripts/test_apache2.sh index 7ebaaa5fd..9af39e8bb 100755 --- a/tests/letstest/scripts/test_apache2.sh +++ b/tests/letstest/scripts/test_apache2.sh @@ -50,7 +50,7 @@ fi # instance, Fedora uses Python 3 and Python 2 is not installed. . tests/letstest/scripts/set_python_envvars.sh -"$VENV_SCRIPT" -e acme[dev] -e .[dev,docs] -e certbot-apache +"$VENV_SCRIPT" -e acme[dev] -e certbot[dev,docs] -e certbot-apache sudo "$VENV_PATH/bin/certbot" -v --debug --text --agree-tos \ --renew-by-default --redirect --register-unsafely-without-email \ --domain $PUBLIC_HOSTNAME --server $BOULDER_URL diff --git a/tests/letstest/scripts/test_leauto_upgrades.sh b/tests/letstest/scripts/test_leauto_upgrades.sh index 541f54f6b..fc7632793 100755 --- a/tests/letstest/scripts/test_leauto_upgrades.sh +++ b/tests/letstest/scripts/test_leauto_upgrades.sh @@ -117,6 +117,8 @@ if ! diff letsencrypt-auto letsencrypt-auto-source/letsencrypt-auto ; then fi if [ "$RUN_RHEL6_TESTS" = 1 ]; then + # Add the SCL python release to PATH in order to resolve python3 command + PATH="/opt/rh/rh-python36/root/usr/bin:$PATH" if ! command -v python3; then echo "Python3 wasn't properly installed" exit 1 diff --git a/tests/letstest/scripts/test_sdists.sh b/tests/letstest/scripts/test_sdists.sh index 347589e04..204f55d55 100755 --- a/tests/letstest/scripts/test_sdists.sh +++ b/tests/letstest/scripts/test_sdists.sh @@ -1,8 +1,21 @@ #!/bin/sh -xe cd letsencrypt + +# If we're on a RHEL 6 based system, we can be confident Python is already +# installed because the package manager is written in Python. +if command -v python && [ $(python -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//') -eq 26 ]; then + # RHEL/CentOS 6 will need a special treatment, so we need to detect that environment + RUN_RHEL6_TESTS=1 +fi + letsencrypt-auto-source/letsencrypt-auto --install-only -n --debug +if [ "$RUN_RHEL6_TESTS" = 1 ]; then + # Enable the SCL Python 3.6 installed by letsencrypt-auto bootstrap + PATH="/opt/rh/rh-python36/root/usr/bin:$PATH" +fi + PLUGINS="certbot-apache certbot-nginx" PYTHON_MAJOR_VERSION=$(/opt/eff.org/certbot/venv/bin/python --version 2>&1 | cut -d" " -f 2 | cut -d. -f1) TEMP_DIR=$(mktemp -d) @@ -27,7 +40,7 @@ VERSION=$("$PYTHON_NAME" letsencrypt-auto-source/version.py) tools/pip_install.py pytest # build sdists -for pkg_dir in acme . $PLUGINS; do +for pkg_dir in acme certbot $PLUGINS; do cd $pkg_dir python setup.py clean rm -rf build dist diff --git a/tests/letstest/scripts/test_tests.sh b/tests/letstest/scripts/test_tests.sh index 77ef44270..fb86ce4cd 100755 --- a/tests/letstest/scripts/test_tests.sh +++ b/tests/letstest/scripts/test_tests.sh @@ -7,7 +7,7 @@ REPO_ROOT="letsencrypt" LE_AUTO="$REPO_ROOT/letsencrypt-auto-source/letsencrypt-auto" LE_AUTO="$LE_AUTO --debug --no-self-upgrade --non-interactive" -MODULES="acme certbot certbot_apache certbot_nginx" +MODULES="acme certbot certbot-apache certbot-nginx" PIP_INSTALL="$REPO_ROOT/tools/pip_install.py" VENV_NAME=venv @@ -17,10 +17,13 @@ LE_AUTO_SUDO="" VENV_PATH="$VENV_NAME" $LE_AUTO --no-bootstrap --version . $VENV_NAME/bin/activate "$PIP_INSTALL" pytest -# change to an empty directory to ensure CWD doesn't affect tests -cd $(mktemp -d) +# To run tests that aren't packaged in modules, run pytest +# from the repo root. The directory structure should still +# cause the installed packages to be tested while using +# the tests available in the subdirectories. +cd $REPO_ROOT for module in $MODULES ; do echo testing $module - pytest -v --pyargs $module + pytest -v $module done diff --git a/tests/lock_test.py b/tests/lock_test.py index c3eebe3d2..29a77ae17 100644 --- a/tests/lock_test.py +++ b/tests/lock_test.py @@ -15,17 +15,16 @@ import tempfile from cryptography import x509 from cryptography.hazmat.backends import default_backend # TODO: once mypy has cryptography types bundled, type: ignore can be removed. -# See https://github.com/python/typeshed/tree/master/third_party/2/cryptography -from cryptography.hazmat.primitives import serialization, hashes # type: ignore +# See https://github.com/pyca/cryptography/issues/4275 +from cryptography.hazmat.primitives import hashes # type: ignore +from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa -from certbot._internal import lock from certbot import util +from certbot._internal import lock from certbot.compat import filesystem - from certbot.tests import util as test_util - logger = logging.getLogger(__name__) @@ -174,7 +173,7 @@ def setup_certificate(workspace): key_path = os.path.join(workspace, 'cert.key') with open(key_path, 'wb') as file_handle: - file_handle.write(private_key.private_bytes( + file_handle.write(private_key.private_bytes( # type: ignore encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption() diff --git a/tests/modification-check.py b/tests/modification-check.py index 8abc0fbfe..811f369d4 100755 --- a/tests/modification-check.py +++ b/tests/modification-check.py @@ -3,10 +3,11 @@ from __future__ import print_function import os +import shutil import subprocess import sys import tempfile -import shutil + try: from urllib.request import urlretrieve except ImportError: diff --git a/tools/_release.sh b/tools/_release.sh index e228bae99..89f2a3737 100755 --- a/tools/_release.sh +++ b/tools/_release.sh @@ -30,7 +30,6 @@ SUBPKGS_NOT_IN_AUTO="certbot-dns-cloudflare certbot-dns-cloudxns certbot-dns-dig SUBPKGS_IN_AUTO="certbot $SUBPKGS_IN_AUTO_NO_CERTBOT" SUBPKGS_NO_CERTBOT="$SUBPKGS_IN_AUTO_NO_CERTBOT $SUBPKGS_NOT_IN_AUTO" SUBPKGS="$SUBPKGS_IN_AUTO $SUBPKGS_NOT_IN_AUTO" -subpkgs_modules="$(echo $SUBPKGS | sed s/-/_/g)" # certbot_compatibility_test is not packaged because: # - it is not meant to be used by anyone else than Certbot devs # - it causes problems when running pytest - the latter tries to @@ -66,12 +65,12 @@ fi git checkout "$RELEASE_BRANCH" # Update changelog -sed -i "s/master/$(date +'%Y-%m-%d')/" CHANGELOG.md -git add CHANGELOG.md +sed -i "s/master/$(date +'%Y-%m-%d')/" certbot/CHANGELOG.md +git add certbot/CHANGELOG.md git diff --cached git commit -m "Update changelog for $version release" -for pkg_dir in $SUBPKGS_NO_CERTBOT certbot-compatibility-test . +for pkg_dir in $SUBPKGS certbot-compatibility-test do sed -i 's/\.dev0//' "$pkg_dir/setup.py" git add "$pkg_dir/setup.py" @@ -79,8 +78,8 @@ do if [ -f "$pkg_dir/local-oldest-requirements.txt" ]; then sed -i "s/-e acme\[dev\]/acme[dev]==$version/" "$pkg_dir/local-oldest-requirements.txt" sed -i "s/-e acme/acme[dev]==$version/" "$pkg_dir/local-oldest-requirements.txt" - sed -i "s/-e \.\[dev\]/certbot[dev]==$version/" "$pkg_dir/local-oldest-requirements.txt" - sed -i "s/-e \./certbot[dev]==$version/" "$pkg_dir/local-oldest-requirements.txt" + sed -i "s/-e certbot\[dev\]/certbot[dev]==$version/" "$pkg_dir/local-oldest-requirements.txt" + sed -i "s/-e certbot/certbot[dev]==$version/" "$pkg_dir/local-oldest-requirements.txt" git add "$pkg_dir/local-oldest-requirements.txt" fi done @@ -97,7 +96,7 @@ SetVersion() { fi sed -i "s/^version.*/version = '$ver'/" $pkg_dir/setup.py done - init_file="certbot/__init__.py" + init_file="certbot/certbot/__init__.py" if [ $(grep -c '^__version' "$init_file") != 1 ]; then echo "Unexpected count of __version variables in $init_file" exit 1 @@ -113,7 +112,7 @@ SetVersion "$version" # conditionals like the one found in certbot-dns-dnsimple's setup.py file. unset CERTBOT_OLDEST echo "Preparing sdists and wheels" -for pkg_dir in . $SUBPKGS_NO_CERTBOT +for pkg_dir in $SUBPKGS do cd $pkg_dir @@ -133,8 +132,7 @@ done mkdir "dist.$version" -mv dist "dist.$version/certbot" -for pkg_dir in $SUBPKGS_NO_CERTBOT +for pkg_dir in $SUBPKGS do mv $pkg_dir/dist "dist.$version/$pkg_dir/" done @@ -163,7 +161,7 @@ cd ~- # get a snapshot of the CLI help for the docs # We set CERTBOT_DOCS to use dummy values in example user-agent string. -CERTBOT_DOCS=1 certbot --help all > docs/cli-help.txt +CERTBOT_DOCS=1 certbot --help all > certbot/docs/cli-help.txt jws --help > acme/docs/jws-help.txt cd .. @@ -177,12 +175,12 @@ mkdir kgs kgs="kgs/$version" pip freeze | tee $kgs python ../tools/pip_install.py pytest -for module in $subpkgs_modules ; do +cd ~- +for module in $SUBPKGS ; do echo testing $module # use an empty configuration file rather than the one in the repo root - pytest -c <(echo '') --pyargs $module + pytest -c <(echo '') $module done -cd ~- # pin pip hashes of the things we just built for pkg in $SUBPKGS_IN_AUTO ; do @@ -231,7 +229,7 @@ mv letsencrypt-auto-source/letsencrypt-auto.asc letsencrypt-auto-source/certbot- cp -p letsencrypt-auto-source/letsencrypt-auto certbot-auto cp -p letsencrypt-auto-source/letsencrypt-auto letsencrypt-auto -git add certbot-auto letsencrypt-auto letsencrypt-auto-source docs/cli-help.txt +git add certbot-auto letsencrypt-auto letsencrypt-auto-source certbot/docs/cli-help.txt git diff --cached while ! git commit --gpg-sign="$RELEASE_GPG_KEY" -m "Release $version"; do echo "Unable to sign the release commit using git." @@ -251,17 +249,17 @@ echo gpg2 -U $RELEASE_GPG_KEY --detach-sign --armor $name.$rev.tar.xz cd ~- # Add master section to CHANGELOG.md -header=$(head -n 4 CHANGELOG.md) +header=$(head -n 4 certbot/CHANGELOG.md) body=$(sed s/nextversion/$nextversion/ tools/_changelog_top.txt) -footer=$(tail -n +5 CHANGELOG.md) +footer=$(tail -n +5 certbot/CHANGELOG.md) echo "$header $body -$footer" > CHANGELOG.md -git add CHANGELOG.md +$footer" > certbot/CHANGELOG.md +git add certbot/CHANGELOG.md git diff --cached -git commit -m "Add contents to CHANGELOG.md for next version" +git commit -m "Add contents to certbot/CHANGELOG.md for next version" echo "New root: $root" echo "Test commands (in the letstest repo):" diff --git a/tools/_venv_common.py b/tools/_venv_common.py index 0898f4f50..c61385054 100644 --- a/tools/_venv_common.py +++ b/tools/_venv_common.py @@ -12,17 +12,17 @@ VENV_NAME. from __future__ import print_function -import os -import shutil import glob -import time +import os +import re +import shutil import subprocess import sys -import re +import time REQUIREMENTS = [ '-e acme[dev]', - '-e .[dev,docs]', + '-e certbot[dev,docs]', '-e certbot-apache', '-e certbot-dns-cloudflare', '-e certbot-dns-cloudxns', diff --git a/tools/deactivate.py b/tools/deactivate.py index d43b84552..10c9ecd35 100644 --- a/tools/deactivate.py +++ b/tools/deactivate.py @@ -16,8 +16,8 @@ import os import sys from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import rsa import josepy as jose from acme import client as acme_client diff --git a/tools/deps.sh b/tools/deps.sh deleted file mode 100755 index e12f201a5..000000000 --- a/tools/deps.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# Find all Python imports. -# -# ./tools/deps.sh certbot -# ./tools/deps.sh acme -# ./tools/deps.sh certbot-apache -# ... -# -# Manually compare the output with deps in setup.py. - -git grep -h -E '^(import|from.*import)' $1/ | \ - awk '{print $2}' | \ - grep -vE "^$1" | \ - sort -u diff --git a/tools/dev_constraints.txt b/tools/dev_constraints.txt index 6854be466..d5d78c96a 100644 --- a/tools/dev_constraints.txt +++ b/tools/dev_constraints.txt @@ -6,13 +6,16 @@ alabaster==0.7.10 apipkg==1.4 appnope==0.1.0 asn1crypto==0.22.0 -astroid==1.6.5 +astroid==2.3.3 attrs==17.3.0 Babel==2.5.1 backports.functools-lru-cache==1.5 backports.shutil-get-terminal-size==1.0.0 +backports.ssl-match-hostname==3.7.0.1 +bcrypt==3.1.6 boto3==1.9.36 botocore==1.12.36 +cached-property==1.5.1 cloudflare==1.5.1 codecov==2.0.15 configparser==3.7.4 @@ -21,8 +24,14 @@ coverage==4.5.4 decorator==4.1.2 dns-lexicon==3.2.1 dnspython==1.15.0 +docker==3.7.2 +docker-compose==1.25.0 +docker-pycreds==0.4.0 +dockerpty==0.4.1 +docopt==0.6.2 docutils==0.12 execnet==1.5.0 +functools32==3.2.3.post2 future==0.16.0 futures==3.1.1 filelock==3.0.12 @@ -33,20 +42,23 @@ importlib-metadata==0.23 ipdb==0.10.2 ipython==5.5.0 ipython-genutils==0.2.0 -isort==4.2.5 +isort==4.3.21 Jinja2==2.9.6 jmespath==0.9.3 josepy==1.1.0 -lazy-object-proxy==1.3.1 +jsonschema==2.6.0 +lazy-object-proxy==1.4.3 logger==1.4 logilab-common==1.4.1 MarkupSafe==1.0 mccabe==0.6.1 more-itertools==5.0.0 -mypy==0.600 +mypy==0.710 +mypy-extensions==0.4.3 ndg-httpsclient==0.3.2 oauth2client==4.0.0 packaging==19.2 +paramiko==2.4.2 pathlib2==2.3.0 pexpect==4.7.0 pickleshare==0.7.4 @@ -58,9 +70,10 @@ py==1.8.0 pyasn1==0.1.9 pyasn1-modules==0.0.10 Pygments==2.2.0 -pylint==1.9.4 +pylint==2.4.3 # If pynsist version is upgraded, our NSIS template windows-installer/template.nsi # must be upgraded if necessary using the new built-in one from pynsist. +pynacl==1.3.0 pynsist==2.4 pytest==3.2.5 pytest-cov==2.5.1 @@ -70,7 +83,7 @@ pytest-sugar==0.9.2 pytest-rerunfailures==4.2 python-dateutil==2.6.1 python-digitalocean==1.11 -pywin32==225 +pywin32==227 PyYAML==3.13 repoze.sphinx.autointerface==0.8 requests-file==1.4.2 @@ -84,16 +97,18 @@ snowballstemmer==1.2.1 Sphinx==1.7.5 sphinx-rtd-theme==0.2.4 sphinxcontrib-websupport==1.0.1 +texttable==0.9.1 tldextract==2.2.0 toml==0.10.0 tox==3.14.0 tqdm==4.19.4 traitlets==4.3.2 twine==1.11.0 -typed-ast==1.1.0 +typed-ast==1.4.0 typing==3.6.4 uritemplate==3.0.0 virtualenv==16.6.2 wcwidth==0.1.7 -wrapt==1.11.1 +websocket-client==0.56.0 +wrapt==1.11.2 zipp==0.6.0 diff --git a/tools/extract_changelog.py b/tools/extract_changelog.py index d3bd2aa44..fb0b849aa 100755 --- a/tools/extract_changelog.py +++ b/tools/extract_changelog.py @@ -1,9 +1,9 @@ #!/usr/bin/env python from __future__ import print_function -import sys + import os import re - +import sys CERTBOT_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) @@ -16,7 +16,7 @@ def main(): section_pattern = re.compile(r'^##\s*{0}\s*-\s*[\d-]+$' .format(version.replace('.', '\\.'))) - with open(os.path.join(CERTBOT_ROOT, 'CHANGELOG.md')) as file_h: + with open(os.path.join(CERTBOT_ROOT, 'certbot', 'CHANGELOG.md')) as file_h: lines = file_h.read().splitlines() changelog = [] diff --git a/tools/install_and_test.py b/tools/install_and_test.py index 6987cf2b1..192708957 100755 --- a/tools/install_and_test.py +++ b/tools/install_and_test.py @@ -8,18 +8,16 @@ from __future__ import print_function import os -import sys -import tempfile -import shutil -import subprocess import re +import subprocess +import sys SKIP_PROJECTS_ON_WINDOWS = ['certbot-apache', 'letshelp-certbot'] -def call_with_print(command, cwd=None): +def call_with_print(command): print(command) - subprocess.check_call(command, shell=True, cwd=cwd or os.getcwd()) + subprocess.check_call(command, shell=True) def main(args): @@ -41,16 +39,8 @@ def main(args): call_with_print(' '.join(current_command)) pkg = re.sub(r'\[\w+\]', '', requirement) - if pkg == '.': - pkg = 'certbot' - - temp_cwd = tempfile.mkdtemp() - shutil.copy2("pytest.ini", temp_cwd) - try: - call_with_print(' '.join([ - sys.executable, '-m', 'pytest', '--pyargs', pkg.replace('-', '_')]), cwd=temp_cwd) - finally: - shutil.rmtree(temp_cwd) + call_with_print(' '.join([ + sys.executable, '-m', 'pytest', pkg])) if __name__ == '__main__': main(sys.argv[1:]) diff --git a/tools/pip_install.py b/tools/pip_install.py index cf0a7aee5..0a3961384 100755 --- a/tools/pip_install.py +++ b/tools/pip_install.py @@ -8,13 +8,14 @@ # CERTBOT_OLDEST is set, this script must be run with `-e ` and # no other arguments. -from __future__ import print_function, absolute_import +from __future__ import absolute_import +from __future__ import print_function -import subprocess import os -import sys import re import shutil +import subprocess +import sys import tempfile import merge_requirements as merge_module @@ -69,9 +70,9 @@ def merge_requirements(tools_path, requirements, test_constraints, all_constrain fd.write(merged_requirements) -def call_with_print(command, cwd=None): +def call_with_print(command): print(command) - subprocess.check_call(command, shell=True, cwd=cwd or os.getcwd()) + subprocess.check_call(command, shell=True) def pip_install_with_print(args_str): diff --git a/tools/pip_install_editable.py b/tools/pip_install_editable.py index 8eaf3a9fa..3f7c02ba9 100755 --- a/tools/pip_install_editable.py +++ b/tools/pip_install_editable.py @@ -8,6 +8,7 @@ import sys import pip_install + def main(args): new_args = [] for arg in args: diff --git a/tools/readlink.py b/tools/readlink.py index 0199ce184..446c8ebdc 100755 --- a/tools/readlink.py +++ b/tools/readlink.py @@ -11,6 +11,7 @@ from __future__ import print_function import os import sys + def main(link): return os.path.realpath(link) diff --git a/tools/simple_http_server.py b/tools/simple_http_server.py index 233aa6bd3..24c55962d 100755 --- a/tools/simple_http_server.py +++ b/tools/simple_http_server.py @@ -1,6 +1,7 @@ #!/usr/bin/env python """A version of Python's SimpleHTTPServer that flushes its output.""" import sys + try: from http.server import HTTPServer, SimpleHTTPRequestHandler except ImportError: diff --git a/tools/sphinx-quickstart.sh b/tools/sphinx-quickstart.sh index 72dc9e200..35a7f7fad 100755 --- a/tools/sphinx-quickstart.sh +++ b/tools/sphinx-quickstart.sh @@ -14,7 +14,7 @@ sed -i -e "s|\# import os|import os|" conf.py sed -i -e "s|\# needs_sphinx = '1.0'|needs_sphinx = '1.0'|" conf.py sed -i -e "s|intersphinx_mapping = {'https://docs.python.org/': None}|intersphinx_mapping = {\n 'python': ('https://docs.python.org/', None),\n 'acme': ('https://acme-python.readthedocs.org/en/latest/', None),\n 'certbot': ('https://certbot.eff.org/docs/', None),\n}|" conf.py sed -i -e "s|html_theme = 'alabaster'|\n# http://docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs\n# on_rtd is whether we are on readthedocs.org\non_rtd = os.environ.get('READTHEDOCS', None) == 'True'\nif not on_rtd: # only import and set the theme if we're building docs locally\n import sphinx_rtd_theme\n html_theme = 'sphinx_rtd_theme'\n html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]\n# otherwise, readthedocs.org uses their theme by default, so no need to specify it|" conf.py -sed -i -e "s|# Add any paths that contain templates here, relative to this directory.|autodoc_member_order = 'bysource'\nautodoc_default_flags = ['show-inheritance', 'private-members']\n\n# Add any paths that contain templates here, relative to this directory.|" conf.py +sed -i -e "s|# Add any paths that contain templates here, relative to this directory.|autodoc_member_order = 'bysource'\nautodoc_default_flags = ['show-inheritance']\n\n# Add any paths that contain templates here, relative to this directory.|" conf.py sed -i -e "s|# The name of the Pygments (syntax highlighting) style to use.|default_role = 'py:obj'\n\n# The name of the Pygments (syntax highlighting) style to use.|" conf.py echo "/_build/" >> .gitignore echo "================= diff --git a/tools/venv.py b/tools/venv.py index 6cd38cfc0..f99386eff 100755 --- a/tools/venv.py +++ b/tools/venv.py @@ -5,6 +5,7 @@ import sys import _venv_common + def create_venv(venv_path): """Create a Python 2 virtual environment at venv_path. diff --git a/tools/venv3.py b/tools/venv3.py index 77a30763d..7ead82bd5 100755 --- a/tools/venv3.py +++ b/tools/venv3.py @@ -21,7 +21,7 @@ def main(pip_args=None): create_venv(venv_path) if not pip_args: - pip_args = _venv_common.REQUIREMENTS + ['-e .[dev3]'] + pip_args = _venv_common.REQUIREMENTS + ['-e certbot[dev3]'] _venv_common.install_packages(venv_path, pip_args) diff --git a/tox.cover.py b/tox.cover.py index 6981bbb41..0ef5c0d07 100755 --- a/tox.cover.py +++ b/tox.cover.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import argparse -import subprocess import os +import subprocess import sys DEFAULT_PACKAGES = [ @@ -16,7 +16,7 @@ COVER_THRESHOLDS = { 'acme': {'linux': 100, 'windows': 99}, 'certbot_apache': {'linux': 100, 'windows': 100}, 'certbot_dns_cloudflare': {'linux': 98, 'windows': 98}, - 'certbot_dns_cloudxns': {'linux': 99, 'windows': 99}, + 'certbot_dns_cloudxns': {'linux': 98, 'windows': 98}, 'certbot_dns_digitalocean': {'linux': 98, 'windows': 98}, 'certbot_dns_dnsimple': {'linux': 98, 'windows': 98}, 'certbot_dns_dnsmadeeasy': {'linux': 99, 'windows': 99}, @@ -47,8 +47,8 @@ def cover(package): .format(pkg_dir))) return - subprocess.check_call([sys.executable, '-m', 'pytest', '--pyargs', - '--cov', pkg_dir, '--cov-append', '--cov-report=', package]) + subprocess.check_call([sys.executable, '-m', 'pytest', + '--cov', pkg_dir, '--cov-append', '--cov-report=', pkg_dir]) subprocess.check_call([ sys.executable, '-m', 'coverage', 'report', '--fail-under', str(threshold), '--include', '{0}/*'.format(pkg_dir), '--show-missing']) diff --git a/tox.ini b/tox.ini index 04715cc2f..3a31558d8 100644 --- a/tox.ini +++ b/tox.ini @@ -31,7 +31,7 @@ dns_packages = certbot-dns-sakuracloud all_packages = acme[dev] \ - .[dev] \ + certbot[dev] \ certbot-apache \ {[base]dns_packages} \ certbot-nginx \ @@ -40,7 +40,7 @@ install_packages = python {toxinidir}/tools/pip_install_editable.py {[base]all_packages} source_paths = acme/acme - certbot + certbot/certbot certbot-apache/certbot_apache certbot-compatibility-test/certbot_compatibility_test certbot-dns-cloudflare/certbot_dns_cloudflare @@ -92,7 +92,7 @@ setenv = [testenv:py27-certbot-oldest] commands = - {[base]install_and_test} .[dev] + {[base]install_and_test} certbot[dev] setenv = {[testenv:py27-oldest]setenv} @@ -122,36 +122,37 @@ commands = python tox.cover.py [testenv:lint] -basepython = python2.7 +basepython = python3 # separating into multiple invocations disables cross package # duplicate code checking; if one of the commands fails, others will # continue, but tox return code will reflect previous error commands = {[base]install_packages} + {[base]pip_install} certbot[dev3] python -m pylint --reports=n --rcfile=.pylintrc {[base]source_paths} [testenv:mypy] basepython = python3 commands = {[base]install_packages} - {[base]pip_install} .[dev3] + {[base]pip_install} certbot[dev3] mypy {[base]source_paths} [testenv:apacheconftest] commands = - {[base]pip_install} acme . certbot-apache certbot-compatibility-test - {toxinidir}/certbot-apache/certbot_apache/tests/apache-conf-files/apache-conf-test --debian-modules + {[base]pip_install} acme certbot certbot-apache certbot-compatibility-test + {toxinidir}/certbot-apache/tests/apache-conf-files/apache-conf-test --debian-modules passenv = SERVER [testenv:apacheconftest-with-pebble] commands = - {[base]pip_install} acme . certbot-apache certbot-ci certbot-compatibility-test - {toxinidir}/certbot-apache/certbot_apache/tests/apache-conf-files/apache-conf-test-pebble.py --debian-modules + {[base]pip_install} acme certbot certbot-apache certbot-ci certbot-compatibility-test + {toxinidir}/certbot-apache/tests/apache-conf-files/apache-conf-test-pebble.py --debian-modules [testenv:nginxroundtrip] commands = - {[base]pip_install} acme . certbot-apache certbot-nginx + {[base]pip_install} acme certbot certbot-apache certbot-nginx python certbot-compatibility-test/nginx/roundtrip.py certbot-compatibility-test/nginx/nginx-roundtrip-testdata # This is a duplication of the command line in testenv:le_auto to @@ -206,7 +207,17 @@ passenv = DOCKER_* # At the moment, this tests under Python 2.6 only, as only that version is # readily available on the CentOS 6 Docker image. commands = - docker build -f letsencrypt-auto-source/Dockerfile.centos6 -t lea letsencrypt-auto-source + docker build -f letsencrypt-auto-source/Dockerfile.redhat6 --build-arg REDHAT_DIST_FLAVOR=centos -t lea letsencrypt-auto-source + docker run --rm -t -i lea +whitelist_externals = + docker +passenv = DOCKER_* + +[testenv:le_auto_oraclelinux6] +# At the moment, this tests under Python 2.6 only, as only that version is +# readily available on the Oracle Linux 6 Docker image. +commands = + docker build -f letsencrypt-auto-source/Dockerfile.redhat6 --build-arg REDHAT_DIST_FLAVOR=oraclelinux -t lea letsencrypt-auto-source docker run --rm -t -i lea whitelist_externals = docker @@ -223,7 +234,7 @@ passenv = DOCKER_* [testenv:integration] commands = - {[base]pip_install} acme . certbot-nginx certbot-ci + {[base]pip_install} acme certbot certbot-nginx certbot-ci pytest certbot-ci/certbot_integration_tests \ --acme-server={env:ACME_SERVER:pebble} \ --cov=acme --cov=certbot --cov=certbot_nginx --cov-report= \ @@ -234,7 +245,7 @@ passenv = DOCKER_* [testenv:integration-certbot] commands = - {[base]pip_install} acme . certbot-ci + {[base]pip_install} acme certbot certbot-ci pytest certbot-ci/certbot_integration_tests/certbot_tests \ --acme-server={env:ACME_SERVER:pebble} \ --cov=acme --cov=certbot --cov-report= \ @@ -243,7 +254,7 @@ commands = [testenv:integration-certbot-oldest] commands = - {[base]pip_install} . + {[base]pip_install} certbot {[base]pip_install} certbot-ci pytest certbot-ci/certbot_integration_tests/certbot_tests \ --acme-server={env:ACME_SERVER:pebble} diff --git a/windows-installer/construct.py b/windows-installer/construct.py index 089296439..77ca67e65 100644 --- a/windows-installer/construct.py +++ b/windows-installer/construct.py @@ -1,17 +1,17 @@ #!/usr/bin/env python3 import contextlib import ctypes +import os +import shutil import struct import subprocess -import os import sys -import shutil import tempfile import time PYTHON_VERSION = (3, 7, 4) PYTHON_BITNESS = 32 -PYWIN32_VERSION = 225 # do not forget to edit pywin32 dependency accordingly in setup.py +PYWIN32_VERSION = 227 # do not forget to edit pywin32 dependency accordingly in setup.py NSIS_VERSION = '3.04' @@ -40,7 +40,7 @@ def _compile_wheels(repo_path, build_path, venv_python): wheels_path = os.path.join(build_path, 'wheels') os.makedirs(wheels_path) - certbot_packages = ['acme', '.'] + certbot_packages = ['acme', 'certbot'] # Uncomment following line to include all DNS plugins in the installer # certbot_packages.extend([name for name in os.listdir(repo_path) if name.startswith('certbot-dns-')]) wheels_project = [os.path.join(repo_path, package) for package in certbot_packages] @@ -119,8 +119,9 @@ imp.load_dynamic('pythoncom', pcom) installer_cfg_path = os.path.join(build_path, 'installer.cfg') + certbot_pkg_path = os.path.join(repo_path, 'certbot') certbot_version = subprocess.check_output([sys.executable, '-c', 'import certbot; print(certbot.__version__)'], - universal_newlines=True, cwd=repo_path).strip() + universal_newlines=True, cwd=certbot_pkg_path).strip() with open(installer_cfg_path, 'w') as file_h: file_h.write('''\ @@ -147,7 +148,7 @@ files=run.bat renew-down.ps1 [Command certbot] -entry_point=certbot._internal.main:main +entry_point=certbot.main:main extra_preamble=pywin32_paths.py '''.format(certbot_version=certbot_version, installer_suffix='win_amd64' if PYTHON_BITNESS == 64 else 'win32', diff --git a/windows-installer/renew-up.ps1 b/windows-installer/renew-up.ps1 index c6a5fd9ea..224458748 100644 --- a/windows-installer/renew-up.ps1 +++ b/windows-installer/renew-up.ps1 @@ -8,8 +8,10 @@ $action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '-NoProfil $delay = New-TimeSpan -Hours 12 $triggerAM = New-ScheduledTaskTrigger -Daily -At 12am -RandomDelay $delay $triggerPM = New-ScheduledTaskTrigger -Daily -At 12pm -RandomDelay $delay -# NB: For now scheduled task is set up under SYSTEM account because Certbot Installer installs Certbot for all users. +# NB: For now scheduled task is set up under Administrators group account because Certbot Installer installs Certbot for all users. # If in the future we allow the Installer to install Certbot for one specific user, the scheduled task will need to # switch to this user, since Certbot will be available only for him. -$principal = New-ScheduledTaskPrincipal -UserId SYSTEM -LogonType ServiceAccount -RunLevel Highest +$adminsSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544") +$adminsGroupID = $adminsSID.Translate([System.Security.Principal.NTAccount]).Value +$principal = New-ScheduledTaskPrincipal -GroupId $adminsGroupID -RunLevel Highest Register-ScheduledTask -Action $action -Trigger $triggerAM,$triggerPM -TaskName $taskName -Description "Execute twice a day the 'certbot renew' command, to renew managed certificates if needed." -Principal $principal