go-acme / lego

Let's Encrypt/ACME client and library written in Go
https://go-acme.github.io/lego/
MIT License
7.44k stars 985 forks source link

'--dns exec' show output in real time? #2165

Closed kg4zow closed 2 months ago

kg4zow commented 2 months ago

Welcome

How do you use lego?

Binary

Detailed Description

I'm working on a shell script to use with --dns exec (to manually add/remove DNS records), and running into issues that take significantly longer than they should to debug, because the part of lego which runs my script appears to be gathering the script's output in memory and then dumping it to the output stream all at once. The process of adding/removing DNS records can take up to two minutes per name, so if I'm testing with a certificate having multiple hostnames on it (i.e. name1.domain.xyz, 'name2.domain.xyz, and name3.domain.xyz), I see no output at all for several minutes and then get a dump all at once at the end.

I'm looking at providers/dns/exec/exec.go, but I don't know enough about the exec module to know if this is even possible, so ... is there a way to make the code print each line of input, as soon as the external script prints it?

ldez commented 2 months ago

Hello,

first, what drives you to use exec instead of "real" DNS implementation? Is your provider not supported?

kg4zow commented 2 months ago

Exactly. I've been running my own DNS servers using tinydns for over 20 years. The process of adding a record in tinydns involves (1) adding a line to a text file, and (2) running a command to "compile" the data files into a .cdb file (similar to Berkeley DB).

My own implementation has a Makefile which pushes the .cdb file out to several other machines, and THOSE machines are the public nameservers. My "API server" involves clients using SSH to add and remove records, this has been working for about 10 years when I started using acme.sh. (I'm looking for alternatives, so far lego seems like a better option than certbot but I'm not 100% sold either way - although I do have a bit of a preference for Golang over Python.)

I'm also in the process of learning golang, so it's not impossible that if nobody else has time to look at it, I might take the time to figure it out myself. It looks like I would need to replace the cmd.CombinedOutput() call with cmd.Start(), and add loops or "go-routines" after that which print the STDOUT/STDERR output as it arrives. (I think I see how to do it, it's just not something I've ever done in golang before.)

The other option I'm considering is, instead of writing a script around lego, writing my own client that uses lego as a library. I may do this anyway, but it won't happen any time soon. The only "non-standard" thing I'm doing is the DNS records, so if I can use an established client with a simple plug-in script to handle my own custom needs, I'd rather go that route.

ldez commented 2 months ago

Thank you for your detailed answer :+1:

FYI, I created a PR to stream the script output: #2166