Repository: certbot/certbot

Issue:
--cert-name option not honored on new SSL certificate issuance
Hello,

```shell
root@stretch:~# certbot-auto --version
certbot 0.11.1
```
```shell
# certbot-auto \
certonly \
--non-interactive \
--agree-tos --email <email> \
--staging \
--webroot --webroot-path <path> \
--allow-subset-of-names \
--domain unresolvable.domain.tld \
--domain resolvable.domain.tld \
--cert-name unresolvable.domain.tld
```
Result in:
```shell
No certificate found with name unresolvable.domain.tld (expected /etc/letsencrypt/renewal/unresolvable.domain.tld.conf).
```
But help say (When creating a new certificate ...):
```
--cert-name CERTNAME  Certificate name to apply. Only one certificate name
                        can be used per Certbot run. To see certificate names,
                        run 'certbot certificates'. When creating a new
                        certificate, specifies the new certificate's name.
                        (default: None)
```

Thank you.


Discussion:
cc @ohemorange 
Furthermore:

For us, it would be much appreciated to have the `--cert-name` command line option also working for new SSL certificate issuances, allowing us to specify lineage name explicitely. This is needed in our case because our plugin acts as per lineage basis.

In the command above, even if there is an auth failure for the `unresolvable.domain.tld` domain, we want it as the lineage name. Our plugin use that lineage name for internal retrieval. Right now, it seem that the first SAN passed in to certbot (`--domain <SAN>`) is always used as lineage name but it would be more practicable to make this explicite using the `--cert-name` option as stated in its current description.
This is a regression caused by #4128. Looking into a solution.
@ohemorange 

Thank for taking this in consideration. That is much appreciated.

Resolving patch:
diff --git a/certbot/cert_manager.py b/certbot/cert_manager.py
--- a/certbot/cert_manager.py
+++ b/certbot/cert_manager.py
@@ -100,7 +100,10 @@ def lineage_for_certname(cli_config, certname):
     configs_dir = cli_config.renewal_configs_dir
     # Verify the directory is there
     util.make_or_verify_dir(configs_dir, mode=0o755, uid=os.geteuid())
-    renewal_file = storage.renewal_file_for_certname(cli_config, certname)
+    try:
+        renewal_file = storage.renewal_file_for_certname(cli_config, certname)
+    except errors.CertStorageError:
+        return None
     try:
         return storage.RenewableCert(renewal_file, cli_config)
     except (errors.CertStorageError, IOError):


Test patch:
diff --git a/certbot/tests/cert_manager_test.py b/certbot/tests/cert_manager_test.py
--- a/certbot/tests/cert_manager_test.py
+++ b/certbot/tests/cert_manager_test.py
@@ -290,6 +290,16 @@ def test_no_match(self, mock_renewal_conf_file,
             None)
         self.assertTrue(mock_make_or_verify_dir.called)
 
+    @mock.patch('certbot.util.make_or_verify_dir')
+    @mock.patch('certbot.storage.renewal_file_for_certname')
+    def test_no_renewal_file(self, mock_renewal_conf_file,
+        mock_make_or_verify_dir):
+        mock_renewal_conf_file.side_effect = errors.CertStorageError()
+        from certbot import cert_manager
+        self.assertEqual(cert_manager.lineage_for_certname(self.cli_config, "example.com"),
+            None)
+        self.assertTrue(mock_make_or_verify_dir.called)
+
 
 class DomainsForCertnameTest(BaseCertManagerTest):
     """Tests for certbot.cert_manager.domains_for_certname"""
diff --git a/tests/boulder-integration.sh b/tests/boulder-integration.sh
--- a/tests/boulder-integration.sh
+++ b/tests/boulder-integration.sh
@@ -100,6 +100,8 @@ common certonly -a manual -d le.wtf --rsa-key-size 4096 \
 common certonly -a manual -d dns.le.wtf --preferred-challenges dns,tls-sni \
     --manual-auth-hook ./tests/manual-dns-auth.sh
 
+common certonly --cert-name newname -d newname.le.wtf
+
 export CSR_PATH="${root}/csr.der" KEY_PATH="${root}/key.pem" \
        OPENSSL_CNF=examples/openssl.cnf
 ./examples/generate-csr.sh le3.wtf