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

Issue:
hope to add a delay to the `dns.disable-cp` parameter
### Welcome

- [X] Yes, I've searched similar issues on GitHub and didn't find any.

### How do you use lego?

Binary

### Detailed Description

I don't know why dns validation often fails, so I used `dns.disable-cp`. However, there are often cases where the parsing record has not yet been completed and takes effect. I hope to add a delay, such as 10 seconds, and then execute the next step. It is best to customize the delay time unit as seconds.

like:

`./lego --dns.disable-cp 15`


Thank you to everyone involved in this project :)


Discussion / hints:
stuck with this issue also... using dns.he.net. I'm updating my certs regularly by cron with simple script and for some reason dns check does not work correctly (maybe coz all networks's dns requests are redirected to caching local dns server, which increasing delay of updating records). for some reason, updating key in dns.he.net are helps for one time...

Fix patch:
diff --git a/cmd/flags.go b/cmd/flags.go
index cd21c466bb..dd9fb74630 100644
--- a/cmd/flags.go
+++ b/cmd/flags.go
@@ -113,6 +113,10 @@ func CreateFlags(defaultPath string) []cli.Flag {
 			Name:  "dns.disable-cp",
 			Usage: "By setting this flag to true, disables the need to await propagation of the TXT record to all authoritative name servers.",
 		},
+		&cli.DurationFlag{
+			Name:  "dns.propagation-wait",
+			Usage: "By setting this flag, disables all the propagation checks and uses a wait duration instead.",
+		},
 		&cli.StringSliceFlag{
 			Name: "dns.resolvers",
 			Usage: "Set the resolvers to use for performing (recursive) CNAME resolving and apex domain determination." +
diff --git a/cmd/setup_challenges.go b/cmd/setup_challenges.go
index 719f8dd6cf..271779f9b9 100644
--- a/cmd/setup_challenges.go
+++ b/cmd/setup_challenges.go
@@ -1,6 +1,7 @@
 package cmd
 
 import (
+	"errors"
 	"net"
 	"strings"
 	"time"
@@ -38,7 +39,10 @@ func setupChallenges(ctx *cli.Context, client *lego.Client) {
 	}
 
 	if ctx.IsSet("dns") {
-		setupDNS(ctx, client)
+		err := setupDNS(ctx, client)
+		if err != nil {
+			log.Fatal(err)
+		}
 	}
 }
 
@@ -113,22 +117,40 @@ func setupTLSProvider(ctx *cli.Context) challenge.Provider {
 	}
 }
 
-func setupDNS(ctx *cli.Context, client *lego.Client) {
+func setupDNS(ctx *cli.Context, client *lego.Client) error {
+	if ctx.IsSet("dns.disable-cp") && ctx.Bool("dns.disable-cp") && ctx.IsSet("dns.propagation-wait") {
+		return errors.New("'dns.disable-cp' and 'dns.propagation-wait' are mutually exclusive")
+	}
+
+	wait := ctx.Duration("dns.propagation-wait")
+	if wait < 0 {
+		return errors.New("'dns.propagation-wait' cannot be negative")
+	}
+
 	provider, err := dns.NewDNSChallengeProviderByName(ctx.String("dns"))
 	if err != nil {
-		log.Fatal(err)
+		return err
 	}
 
 	servers := ctx.StringSlice("dns.resolvers")
+
 	err = client.Challenge.SetDNS01Provider(provider,
 		dns01.CondOption(len(servers) > 0,
 			dns01.AddRecursiveNameservers(dns01.ParseNameservers(ctx.StringSlice("dns.resolvers")))),
+
 		dns01.CondOption(ctx.Bool("dns.disable-cp"),
 			dns01.DisableCompletePropagationRequirement()),
+
+		dns01.CondOption(ctx.IsSet("dns.propagation-wait"), dns01.WrapPreCheck(
+			func(domain, fqdn, value string, check dns01.PreCheckFunc) (bool, error) {
+				time.Sleep(wait)
+				return true, nil
+			},
+		)),
+
 		dns01.CondOption(ctx.IsSet("dns-timeout"),
 			dns01.AddDNSTimeout(time.Duration(ctx.Int("dns-timeout"))*time.Second)),
 	)
-	if err != nil {
-		log.Fatal(err)
-	}
+
+	return err
 }
diff --git a/docs/data/zz_cli_help.toml b/docs/data/zz_cli_help.toml
index 7b88974db8..13f291bb75 100644
--- a/docs/data/zz_cli_help.toml
+++ b/docs/data/zz_cli_help.toml
@@ -40,6 +40,7 @@ GLOBAL OPTIONS:
    --tls.port value                                             Set the port and interface to use for TLS-ALPN-01 based challenges to listen on. Supported: interface:port or :port. (default: ":443")
    --dns value                                                  Solve a DNS-01 challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage.
    --dns.disable-cp                                             By setting this flag to true, disables the need to await propagation of the TXT record to all authoritative name servers. (default: false)
+   --dns.propagation-wait value                                 By setting this flag, disables all the propagation checks and uses a wait duration instead. (default: 0s)
    --dns.resolvers value [ --dns.resolvers value ]              Set the resolvers to use for performing (recursive) CNAME resolving and apex domain determination. For DNS-01 challenge verification, the authoritative DNS server is queried directly. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.
    --http-timeout value                                         Set the HTTP timeout value to a specific value in seconds. (default: 0)
    --dns-timeout value                                          Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name server queries. (default: 10)


Test patch: