mirror of
https://github.com/certbot/certbot.git
synced 2026-07-28 00:35:50 +02:00
Merge remote-tracking branch 'upstream/master' into multios_apache
This commit is contained in:
+20
-15
@@ -31,16 +31,21 @@ Firstly, please `install Git`_ and run the following commands:
|
||||
|
||||
.. _`install Git`: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
|
||||
|
||||
.. note:: On RedHat/CentOS 6 you will need to enable the EPEL_
|
||||
repository before install.
|
||||
|
||||
.. _EPEL: http://fedoraproject.org/wiki/EPEL
|
||||
|
||||
To install and run the client you just need to type:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
./letsencrypt-auto
|
||||
|
||||
.. note:: On RedHat/CentOS 6 you will need to enable the EPEL_
|
||||
repository before install.
|
||||
|
||||
.. _EPEL: http://fedoraproject.org/wiki/EPEL
|
||||
.. hint:: During the beta phase, Let's Encrypt enforces strict rate limits on
|
||||
the number of certificates issued for one domain. It is recommended to
|
||||
initially use the test server via `--test-cert` until you get the desired
|
||||
certificates.
|
||||
|
||||
Throughout the documentation, whenever you see references to
|
||||
``letsencrypt`` script/binary, you can substitute in
|
||||
@@ -58,8 +63,8 @@ or for full help, type:
|
||||
|
||||
|
||||
``letsencrypt-auto`` is the recommended method of running the Let's Encrypt
|
||||
client beta releases on systems that don't have a packaged version. Debian
|
||||
experimental, Arch linux and FreeBSD now have native packages, so on those
|
||||
client beta releases on systems that don't have a packaged version. Debian,
|
||||
Arch linux and FreeBSD now have native packages, so on those
|
||||
systems you can just install ``letsencrypt`` (and perhaps
|
||||
``letsencrypt-apache``). If you'd like to run the latest copy from Git, or
|
||||
run your own locally modified copy of the client, follow the instructions in
|
||||
@@ -173,10 +178,10 @@ Renewal
|
||||
In order to renew certificates simply call the ``letsencrypt`` (or
|
||||
letsencrypt-auto_) again, and use the same values when prompted. You
|
||||
can automate it slightly by passing necessary flags on the CLI (see
|
||||
`--help all`), or even further using the :ref:`config-file`. The
|
||||
``--renew-by-default`` flag may be helpful for automating renewal. If
|
||||
you're sure that UI doesn't prompt for any details you can add the
|
||||
command to ``crontab`` (make it less than every 90 days to avoid
|
||||
`--help all`), or even further using the :ref:`config-file`. The
|
||||
``--renew-by-default`` flag may be helpful for automating renewal. If
|
||||
you're sure that UI doesn't prompt for any details you can add the
|
||||
command to ``crontab`` (make it less than every 90 days to avoid
|
||||
problems, say every month).
|
||||
|
||||
Please note that the CA will send notification emails to the address
|
||||
@@ -352,20 +357,20 @@ Operating System Packages
|
||||
|
||||
sudo pacman -S letsencrypt letsencrypt-apache
|
||||
|
||||
**Debian Experimental**
|
||||
**Debian**
|
||||
|
||||
If you run Debian unstable, you can install experimental letsencrypt packages.
|
||||
Add the line ``deb http://ftp.us.debian.org/debian/ experimental main`` (or
|
||||
the equivalent for your country) to ``/etc/apt/sources.list``, then run
|
||||
If you run Debian Stretch or Debian Sid, you can install letsencrypt packages.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get -t experimental install letsencrypt python-letsencrypt-apache
|
||||
sudo apt-get install letsencrypt python-letsencrypt-apache
|
||||
|
||||
If you don't want to use the Apache plugin, you can ommit the
|
||||
``python-letsencrypt-apache`` package.
|
||||
|
||||
Packages for Debian Jessie are coming in the next few weeks.
|
||||
|
||||
**Other Operating Systems**
|
||||
|
||||
OS packaging is an ongoing effort. If you'd like to package
|
||||
|
||||
+9
-7
@@ -1,4 +1,6 @@
|
||||
"""Let's Encrypt CLI."""
|
||||
from __future__ import print_function
|
||||
|
||||
# TODO: Sanity check all input. Be sure to avoid shell code etc...
|
||||
# pylint: disable=too-many-lines
|
||||
# (TODO: split this file into main.py and cli.py)
|
||||
@@ -660,7 +662,7 @@ def plugins_cmd(args, config, plugins): # TODO: Use IDisplay rather than print
|
||||
logger.debug("Filtered plugins: %r", filtered)
|
||||
|
||||
if not args.init and not args.prepare:
|
||||
print str(filtered)
|
||||
print(str(filtered))
|
||||
return
|
||||
|
||||
filtered.init(config)
|
||||
@@ -668,13 +670,13 @@ def plugins_cmd(args, config, plugins): # TODO: Use IDisplay rather than print
|
||||
logger.debug("Verified plugins: %r", verified)
|
||||
|
||||
if not args.prepare:
|
||||
print str(verified)
|
||||
print(str(verified))
|
||||
return
|
||||
|
||||
verified.prepare()
|
||||
available = verified.available()
|
||||
logger.debug("Prepared plugins: %s", available)
|
||||
print str(available)
|
||||
print(str(available))
|
||||
|
||||
|
||||
def read_file(filename, mode="rb"):
|
||||
@@ -767,7 +769,7 @@ class HelpfulArgumentParser(object):
|
||||
self.help_arg = max(help1, help2)
|
||||
if self.help_arg is True:
|
||||
# just --help with no topic; avoid argparse altogether
|
||||
print usage
|
||||
print(usage)
|
||||
sys.exit(0)
|
||||
self.visible_topics = self.determine_help_topics(self.help_arg)
|
||||
self.groups = {} # elements are added by .add_group()
|
||||
@@ -880,12 +882,12 @@ class HelpfulArgumentParser(object):
|
||||
|
||||
"""
|
||||
if self.visible_topics[topic]:
|
||||
#print "Adding visible group " + topic
|
||||
#print("Adding visible group " + topic)
|
||||
group = self.parser.add_argument_group(topic, **kwargs)
|
||||
self.groups[topic] = group
|
||||
return group
|
||||
else:
|
||||
#print "Invisible group " + topic
|
||||
#print("Invisible group " + topic)
|
||||
return self.silent_parser
|
||||
|
||||
def add_plugin_args(self, plugins):
|
||||
@@ -897,7 +899,7 @@ class HelpfulArgumentParser(object):
|
||||
"""
|
||||
for name, plugin_ep in plugins.iteritems():
|
||||
parser_or_group = self.add_group(name, description=plugin_ep.description)
|
||||
#print parser_or_group
|
||||
#print(parser_or_group)
|
||||
plugin_ep.plugin_cls.inject_parser_options(parser_or_group, name)
|
||||
|
||||
def determine_help_topics(self, chosen_topic):
|
||||
|
||||
@@ -123,6 +123,7 @@ def pick_configurator(
|
||||
config, default, plugins, question,
|
||||
(interfaces.IAuthenticator, interfaces.IInstaller))
|
||||
|
||||
|
||||
def get_email(more=False, invalid=False):
|
||||
"""Prompt for valid email address.
|
||||
|
||||
@@ -209,6 +210,7 @@ def choose_names(installer):
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def get_valid_domains(domains):
|
||||
"""Helper method for choose_names that implements basic checks
|
||||
on domain names
|
||||
@@ -226,6 +228,7 @@ def get_valid_domains(domains):
|
||||
continue
|
||||
return valid_domains
|
||||
|
||||
|
||||
def _filter_names(names):
|
||||
"""Determine which names the user would like to select from a list.
|
||||
|
||||
@@ -250,7 +253,41 @@ def _choose_names_manually():
|
||||
"Please enter in your domain name(s) (comma and/or space separated) ")
|
||||
|
||||
if code == display_util.OK:
|
||||
return display_util.separate_list_input(input_)
|
||||
invalid_domains = dict()
|
||||
retry_message = ""
|
||||
try:
|
||||
domain_list = display_util.separate_list_input(input_)
|
||||
except UnicodeEncodeError:
|
||||
domain_list = []
|
||||
retry_message = (
|
||||
"Internationalized domain names are not presently "
|
||||
"supported.{0}{0}Would you like to re-enter the "
|
||||
"names?{0}").format(os.linesep)
|
||||
|
||||
for domain in domain_list:
|
||||
try:
|
||||
le_util.check_domain_sanity(domain)
|
||||
except errors.ConfigurationError as e:
|
||||
invalid_domains[domain] = e.message
|
||||
|
||||
if len(invalid_domains):
|
||||
retry_message = (
|
||||
"One or more of the entered domain names was not valid:"
|
||||
"{0}{0}").format(os.linesep)
|
||||
for domain in invalid_domains:
|
||||
retry_message = retry_message + "{1}: {2}{0}".format(
|
||||
os.linesep, domain, invalid_domains[domain])
|
||||
retry_message = retry_message + (
|
||||
"{0}Would you like to re-enter the names?{0}").format(
|
||||
os.linesep)
|
||||
|
||||
if retry_message:
|
||||
# We had error in input
|
||||
retry = util(interfaces.IDisplay).yesno(retry_message)
|
||||
if retry:
|
||||
return _choose_names_manually()
|
||||
else:
|
||||
return domain_list
|
||||
return []
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ within lineages of successor certificates, according to configuration.
|
||||
.. todo:: Call new installer API to restart servers after deployment
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
@@ -169,7 +171,7 @@ def main(cli_args=sys.argv[1:]):
|
||||
constants.CONFIG_DIRS_MODE, uid)
|
||||
|
||||
for renewal_file in os.listdir(cli_config.renewal_configs_dir):
|
||||
print "Processing", renewal_file
|
||||
print("Processing " + renewal_file)
|
||||
try:
|
||||
# TODO: Before trying to initialize the RenewableCert object,
|
||||
# we could check here whether the combination of the config
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
"""Collects and displays information to the user."""
|
||||
from __future__ import print_function
|
||||
|
||||
import collections
|
||||
import logging
|
||||
import os
|
||||
@@ -75,8 +77,8 @@ class Reporter(object):
|
||||
no_exception = sys.exc_info()[0] is None
|
||||
bold_on = sys.stdout.isatty()
|
||||
if bold_on:
|
||||
print le_util.ANSI_SGR_BOLD
|
||||
print 'IMPORTANT NOTES:'
|
||||
print(le_util.ANSI_SGR_BOLD)
|
||||
print('IMPORTANT NOTES:')
|
||||
first_wrapper = textwrap.TextWrapper(
|
||||
initial_indent=' - ', subsequent_indent=(' ' * 3))
|
||||
next_wrapper = textwrap.TextWrapper(
|
||||
@@ -89,9 +91,9 @@ class Reporter(object):
|
||||
sys.stdout.write(le_util.ANSI_SGR_RESET)
|
||||
bold_on = False
|
||||
lines = msg.text.splitlines()
|
||||
print first_wrapper.fill(lines[0])
|
||||
print(first_wrapper.fill(lines[0]))
|
||||
if len(lines) > 1:
|
||||
print "\n".join(
|
||||
next_wrapper.fill(line) for line in lines[1:])
|
||||
print("\n".join(
|
||||
next_wrapper.fill(line) for line in lines[1:]))
|
||||
if bold_on:
|
||||
sys.stdout.write(le_util.ANSI_SGR_RESET)
|
||||
|
||||
@@ -397,6 +397,44 @@ class ChooseNamesTest(unittest.TestCase):
|
||||
self.assertEqual(get_valid_domains(all_invalid), [])
|
||||
self.assertEqual(len(get_valid_domains(two_valid)), 2)
|
||||
|
||||
@mock.patch("letsencrypt.display.ops.util")
|
||||
def test_choose_manually(self, mock_util):
|
||||
from letsencrypt.display.ops import _choose_names_manually
|
||||
# No retry
|
||||
mock_util().yesno.return_value = False
|
||||
# IDN and no retry
|
||||
mock_util().input.return_value = (display_util.OK,
|
||||
"uniçodé.com")
|
||||
self.assertEqual(_choose_names_manually(), [])
|
||||
# IDN exception with previous mocks
|
||||
with mock.patch("letsencrypt.display.util") as mock_sl:
|
||||
uerror = UnicodeEncodeError('mock', u'',
|
||||
0, 1, 'mock')
|
||||
mock_sl.separate_list_input.side_effect = uerror
|
||||
self.assertEqual(_choose_names_manually(), [])
|
||||
# Punycode and no retry
|
||||
mock_util().input.return_value = (display_util.OK,
|
||||
"xn--ls8h.tld")
|
||||
self.assertEqual(_choose_names_manually(), [])
|
||||
# non-FQDN and no retry
|
||||
mock_util().input.return_value = (display_util.OK,
|
||||
"notFQDN")
|
||||
self.assertEqual(_choose_names_manually(), [])
|
||||
# Two valid domains
|
||||
mock_util().input.return_value = (display_util.OK,
|
||||
("example.com,"
|
||||
"valid.example.com"))
|
||||
self.assertEqual(_choose_names_manually(),
|
||||
["example.com", "valid.example.com"])
|
||||
# Three iterations
|
||||
mock_util().input.return_value = (display_util.OK,
|
||||
"notFQDN")
|
||||
yn = mock.MagicMock()
|
||||
yn.side_effect = [True, True, False]
|
||||
mock_util().yesno = yn
|
||||
_choose_names_manually()
|
||||
self.assertEqual(mock_util().yesno.call_count, 3)
|
||||
|
||||
|
||||
class SuccessInstallationTest(unittest.TestCase):
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
Reference in New Issue
Block a user