mirror of
https://github.com/certbot/certbot.git
synced 2026-06-08 16:22:18 -04:00
Merge pull request #1479 from joohoi/domains_flag
Possibility to use comma separated list of domains in config files and cli
This commit is contained in:
commit
4cfd22e31f
4 changed files with 60 additions and 14 deletions
|
|
@ -18,7 +18,7 @@ letsencrypt_test_nginx () {
|
|||
"$@"
|
||||
}
|
||||
|
||||
letsencrypt_test_nginx --domain nginx.wtf run
|
||||
letsencrypt_test_nginx --domains nginx.wtf run
|
||||
echo | openssl s_client -connect localhost:5001 \
|
||||
| openssl x509 -out $root/nginx.pem
|
||||
diff -q $root/nginx.pem $root/conf/live/nginx.wtf/cert.pem
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ def _find_domains(args, installer):
|
|||
domains = args.domains
|
||||
|
||||
if not domains:
|
||||
raise errors.Error("Please specify --domain, or --installer that "
|
||||
raise errors.Error("Please specify --domains, or --installer that "
|
||||
"will help in domain names autodiscovery")
|
||||
|
||||
return domains
|
||||
|
|
@ -465,9 +465,9 @@ def obtaincert(args, config, plugins):
|
|||
"""Authenticate & obtain cert, but do not install it."""
|
||||
|
||||
if args.domains is not None and args.csr is not None:
|
||||
# TODO: --csr could have a priority, when --domain is
|
||||
# TODO: --csr could have a priority, when --domains is
|
||||
# supplied, check if CSR matches given domains?
|
||||
return "--domain and --csr are mutually exclusive"
|
||||
return "--domains and --csr are mutually exclusive"
|
||||
|
||||
try:
|
||||
# installers are used in auth mode to determine domain names
|
||||
|
|
@ -672,8 +672,32 @@ class HelpfulArgumentParser(object):
|
|||
parsed_args = self.parser.parse_args(self.args)
|
||||
parsed_args.func = self.VERBS[self.verb]
|
||||
|
||||
parsed_args.domains = self._parse_domains(parsed_args.domains)
|
||||
return parsed_args
|
||||
|
||||
def _parse_domains(self, domains):
|
||||
"""Helper function for parse_args() that parses domains from a
|
||||
(possibly) comma separated list and returns list of unique domains.
|
||||
|
||||
:param domains: List of domain flags
|
||||
:type domains: `list` of `string`
|
||||
|
||||
:returns: List of unique domains
|
||||
:rtype: `list` of `string`
|
||||
|
||||
"""
|
||||
|
||||
uniqd = None
|
||||
|
||||
if domains:
|
||||
dlist = []
|
||||
for domain in domains:
|
||||
dlist.extend([d.strip() for d in domain.split(",")])
|
||||
# Make sure we don't have duplicates
|
||||
uniqd = [d for i, d in enumerate(dlist) if d not in dlist[:i]]
|
||||
|
||||
return uniqd
|
||||
|
||||
def determine_verb(self):
|
||||
"""Determines the verb/subcommand provided by the user.
|
||||
|
||||
|
|
@ -811,14 +835,15 @@ def prepare_and_parse_args(plugins, args):
|
|||
None, "-t", "--text", dest="text_mode", action="store_true",
|
||||
help="Use the text output instead of the curses UI.")
|
||||
helpful.add(None, "-m", "--email", help=config_help("email"))
|
||||
# positional arg shadows --domain, instead of appending, and
|
||||
# --domain is useful, because it can be stored in config
|
||||
# positional arg shadows --domains, instead of appending, and
|
||||
# --domains is useful, because it can be stored in config
|
||||
#for subparser in parser_run, parser_auth, parser_install:
|
||||
# subparser.add_argument("domains", nargs="*", metavar="domain")
|
||||
helpful.add(None, "-d", "--domain", dest="domains",
|
||||
helpful.add(None, "-d", "--domains", dest="domains",
|
||||
metavar="DOMAIN", action="append",
|
||||
help="Domain names to apply. Use multiple -d flags if you want "
|
||||
"to specify multiple domains")
|
||||
help="Domain names to apply. For multiple domains you can use "
|
||||
"multiple -d flags or enter a comma separated list of domains"
|
||||
"as a parameter.")
|
||||
helpful.add(
|
||||
None, "--duplicate", dest="duplicate", action="store_true",
|
||||
help="Allow getting a certificate that duplicates an existing one")
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods
|
|||
|
||||
@mock.patch('letsencrypt.cli.display_ops')
|
||||
def test_installer_selection(self, mock_display_ops):
|
||||
self._call(['install', '--domain', 'foo.bar', '--cert-path', 'cert',
|
||||
self._call(['install', '--domains', 'foo.bar', '--cert-path', 'cert',
|
||||
'--key-path', 'key', '--chain-path', 'chain'])
|
||||
self.assertEqual(mock_display_ops.pick_installer.call_count, 1)
|
||||
|
||||
|
|
@ -249,7 +249,7 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods
|
|||
|
||||
def test_certonly_bad_args(self):
|
||||
ret, _, _, _ = self._call(['-d', 'foo.bar', 'certonly', '--csr', CSR])
|
||||
self.assertEqual(ret, '--domain and --csr are mutually exclusive')
|
||||
self.assertEqual(ret, '--domains and --csr are mutually exclusive')
|
||||
|
||||
ret, _, _, _ = self._call(['-a', 'bad_auth', 'certonly'])
|
||||
self.assertEqual(ret, 'The requested bad_auth plugin does not appear to be installed')
|
||||
|
|
@ -272,6 +272,27 @@ class CLITest(unittest.TestCase): # pylint: disable=too-many-public-methods
|
|||
self._call,
|
||||
['-d', '*.wildcard.tld'])
|
||||
|
||||
def test_parse_domains(self):
|
||||
from letsencrypt import cli
|
||||
plugins = disco.PluginsRegistry.find_all()
|
||||
|
||||
short_args = ['-d', 'example.com']
|
||||
namespace = cli.prepare_and_parse_args(plugins, short_args)
|
||||
self.assertEqual(namespace.domains, ['example.com'])
|
||||
|
||||
short_args = ['-d', 'example.com,another.net,third.org,example.com']
|
||||
namespace = cli.prepare_and_parse_args(plugins, short_args)
|
||||
self.assertEqual(namespace.domains, ['example.com', 'another.net',
|
||||
'third.org'])
|
||||
|
||||
long_args = ['--domains', 'example.com']
|
||||
namespace = cli.prepare_and_parse_args(plugins, long_args)
|
||||
self.assertEqual(namespace.domains, ['example.com'])
|
||||
|
||||
long_args = ['--domains', 'example.com,another.net,example.com']
|
||||
namespace = cli.prepare_and_parse_args(plugins, long_args)
|
||||
self.assertEqual(namespace.domains, ['example.com', 'another.net'])
|
||||
|
||||
@mock.patch('letsencrypt.crypto_util.notAfter')
|
||||
@mock.patch('letsencrypt.cli.zope.component.getUtility')
|
||||
def test_certonly_new_request_success(self, mock_get_utility, mock_notAfter):
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ common() {
|
|||
"$@"
|
||||
}
|
||||
|
||||
common --domain le1.wtf --standalone-supported-challenges tls-sni-01 auth
|
||||
common --domain le2.wtf --standalone-supported-challenges http-01 run
|
||||
common --domains le1.wtf --standalone-supported-challenges tls-sni-01 auth
|
||||
common --domains le2.wtf --standalone-supported-challenges http-01 run
|
||||
common -a manual -d le.wtf auth
|
||||
|
||||
export CSR_PATH="${root}/csr.der" KEY_PATH="${root}/key.pem" \
|
||||
|
|
@ -40,7 +40,7 @@ common auth --csr "$CSR_PATH" \
|
|||
openssl x509 -in "${root}/csr/0000_cert.pem" -text
|
||||
openssl x509 -in "${root}/csr/0000_chain.pem" -text
|
||||
|
||||
common --domain le3.wtf install \
|
||||
common --domains le3.wtf install \
|
||||
--cert-path "${root}/csr/cert.pem" \
|
||||
--key-path "${root}/csr/key.pem"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue