Repository: go-acme/lego (language: go)

Issue:
nifcloud: You can only get a certificate with a common name that has the same name as the hostedZone.
<!-- PLEASE FOLLOW THE ISSUE TEMPLATE TO HELP TRIAGE AND SUPPORT! -->

- [x] Yes, I'm using a binary release within 2 latest releases.
- [x] Yes, I've searched similar issues on GitHub and didn't find any.
- [x] Yes, I've included all information below (version, config, etc).

### What did you expect to see?
I want to get a certificate that includes a single host name or a certificate that includes host names separated by dots.

### What did you see instead?
I want to be able to obtain a certificate with the above pattern. The correct code is here. https://github.com/go-acme/lego/pull/1381

### Steps to reproduce
I have a hostedZone on nifcloud called devops.xxx.xxx.xxx (a part of the domain is hidden). In this case, there are only two certificates that can be obtained by specifying --domains:

* devops.xxx.xxx.xxx
* *.devops.xxx.xxx.xxx

I cannot get a certificate containing a single host name or a certificate containing a dotted host name, such as:

* aaa.devops.xxx.xxx.xxx
* *.aaa.devops.xxx.xxx.xxx

![hosted_zone](https://user-images.githubusercontent.com/11570790/113951455-92a3a000-984e-11eb-9f93-6a534ace25e6.PNG)

1. Register a hostedZone called devops.xxx.xxx.xxx with nifcloud.
2. Set NIFCLOUD_ACCESS_KEY_ID and NIFCLOUD_SECRET_ACCESS_KEY.
3. docker run --rm -e NIFCLOUD_ACCESS_KEY_ID=xxxx -e NIFCLOUD_SECRET_ACCESS_KEY=xxxx -v $(pwd)/lego_certificates:/lego goacme/lego --path /lego --email your-name@mail.domain --dns nifcloud --domains aaa.devops.xxx.xxx.xxx --key-type rsa2048 --accept-tos run
4. "No hosted zone found" error occurred.

The execution error log is described below.

### Details

<details><summary>Version of lego</summary>

```console
$ docker run --rm goacme/lego -v
lego version v4.3.1 linux/amd64
```

</details>

<details><summary>Logs</summary>

```console
2021/04/08 00:53:06 [INFO] [aaa.devops.xxx.xxx.xxx] acme: Obtaining bundled SAN certificate
2021/04/08 00:53:06 [INFO] [aaa.devops.xxx.xxx.xxx] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/12167329310
2021/04/08 00:53:06 [INFO] [aaa.devops.xxx.xxx.xxx] acme: Could not find solver for: tls-alpn-01
2021/04/08 00:53:06 [INFO] [aaa.devops.xxx.xxx.xxx] acme: Could not find solver for: http-01
2021/04/08 00:53:06 [INFO] [aaa.devops.xxx.xxx.xxx] acme: use dns-01 solver
2021/04/08 00:53:06 [INFO] [aaa.devops.xxx.xxx.xxx] acme: Preparing to solve DNS-01
2021/04/08 00:53:07 [INFO] [aaa.devops.xxx.xxx.xxx] acme: Cleaning DNS-01 challenge
2021/04/08 00:53:07 [WARN] [aaa.devops.xxx.xxx.xxx] acme: cleaning up failed: nifcloud: failed to change NIFCLOUD record set: an error occurred: No hosted zone found
2021/04/08 00:53:08 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz-v3/12167329310
2021/04/08 00:53:08 Could not obtain certificates:
        error: one or more domains had a problem:
[aaa.devops.xxx.xxx.xxx] [aaa.devops.xxx.xxx.xxx] acme: error presenting token: nifcloud: failed to change NIFCLOUD record set: an error occurred: No hosted zone found
```

</details>



Discussion / hints:
Thanks, I think that your PR #1381 is not a good way to fix the problem, the problem can be fixed by following the same pattern as the other providers:

https://github.com/go-acme/lego/blob/ae7daa7d3321fcefa4aee1bb690b1b7ce9b5c78b/providers/dns/netlify/netlify.go#L106-L111

Fix patch:
diff --git a/providers/dns/nifcloud/nifcloud.go b/providers/dns/nifcloud/nifcloud.go
index d66e9f46c5..2cc17d7d08 100644
--- a/providers/dns/nifcloud/nifcloud.go
+++ b/providers/dns/nifcloud/nifcloud.go
@@ -99,7 +99,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
 func (d *DNSProvider) Present(domain, token, keyAuth string) error {
 	fqdn, value := dns01.GetRecord(domain, keyAuth)
 
-	err := d.changeRecord("CREATE", fqdn, value, domain, d.config.TTL)
+	err := d.changeRecord("CREATE", fqdn, value, d.config.TTL)
 	if err != nil {
 		return fmt.Errorf("nifcloud: %w", err)
 	}
@@ -110,7 +110,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
 func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
 	fqdn, value := dns01.GetRecord(domain, keyAuth)
 
-	err := d.changeRecord("DELETE", fqdn, value, domain, d.config.TTL)
+	err := d.changeRecord("DELETE", fqdn, value, d.config.TTL)
 	if err != nil {
 		return fmt.Errorf("nifcloud: %w", err)
 	}
@@ -123,7 +123,7 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
 	return d.config.PropagationTimeout, d.config.PollingInterval
 }
 
-func (d *DNSProvider) changeRecord(action, fqdn, value, domain string, ttl int) error {
+func (d *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error {
 	name := dns01.UnFqdn(fqdn)
 
 	reqParams := internal.ChangeResourceRecordSetsRequest{
@@ -152,9 +152,14 @@ func (d *DNSProvider) changeRecord(action, fqdn, value, domain string, ttl int)
 		},
 	}
 
-	resp, err := d.client.ChangeResourceRecordSets(domain, reqParams)
+	authZone, err := dns01.FindZoneByFqdn(fqdn)
 	if err != nil {
-		return fmt.Errorf("failed to change NIFCLOUD record set: %w", err)
+		return fmt.Errorf("failed to find zone: %w", err)
+	}
+
+	resp, err := d.client.ChangeResourceRecordSets(dns01.UnFqdn(authZone), reqParams)
+	if err != nil {
+		return fmt.Errorf("failed to change record set: %w", err)
 	}
 
 	statusID := resp.ChangeInfo.ID
@@ -162,7 +167,7 @@ func (d *DNSProvider) changeRecord(action, fqdn, value, domain string, ttl int)
 	return wait.For("nifcloud", 120*time.Second, 4*time.Second, func() (bool, error) {
 		resp, err := d.client.GetChange(statusID)
 		if err != nil {
-			return false, fmt.Errorf("failed to query NIFCLOUD DNS change status: %w", err)
+			return false, fmt.Errorf("failed to query change status: %w", err)
 		}
 		return resp.ChangeInfo.Status == "INSYNC", nil
 	})


Test patch: