102 lines
2.3 KiB
Go
102 lines
2.3 KiB
Go
package dns
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"os/exec"
|
|
"sync"
|
|
|
|
"github.com/stuurmcp/cert-manager-webhook-sthome/pkg/util"
|
|
"k8s.io/klog/v2"
|
|
)
|
|
|
|
const (
|
|
nsupdateCmd = "nsupdate"
|
|
ttl = "7200"
|
|
)
|
|
|
|
type output struct {
|
|
buf *bytes.Buffer
|
|
lines []string
|
|
*sync.Mutex
|
|
}
|
|
|
|
func AddTxtRecord(nameservers []string, domain string, fulldomain string, recordvalue string) error {
|
|
return processTXT("add", nameservers, domain, fulldomain, recordvalue)
|
|
}
|
|
|
|
func DeleteTxtRecord(nameservers []string, domain string, fulldomain string, recordvalue string) error {
|
|
return processTXT("delete", nameservers, domain, fulldomain, recordvalue)
|
|
}
|
|
|
|
func processTXT(action string, nameservers []string, domain string, fulldomain string, recordvalue string) error {
|
|
for _, ns := range nameservers {
|
|
klog.Infof("======= ns: %s =======", ns)
|
|
zone := extractDomainName(domain)
|
|
nsucmd := " gsstsig\n server " + ns + "\n zone " + zone + "\n class IN\n update " + action + " " + fulldomain + " " + ttl + " TXT " + recordvalue + "\n send\n"
|
|
out, err := nsupdate(nsucmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, line := range out.lines {
|
|
klog.Infof(line)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func newOutput() *output {
|
|
return &output{
|
|
buf: &bytes.Buffer{},
|
|
lines: []string{},
|
|
Mutex: &sync.Mutex{},
|
|
}
|
|
}
|
|
|
|
func (rw *output) Write(p []byte) (int, error) {
|
|
rw.Lock()
|
|
defer rw.Unlock()
|
|
return rw.buf.Write(p)
|
|
}
|
|
|
|
func nsupdate(nsucmd string) (*output, error) {
|
|
klog.Infof("nsupdate\n%s", nsucmd) // for debugging
|
|
cmd := exec.Command(nsupdateCmd)
|
|
stdout := newOutput()
|
|
cmd.Stdout = stdout
|
|
stdinR, stdinW := io.Pipe()
|
|
stderrR, stderrW := io.Pipe()
|
|
cmd.Stdin = stdinR
|
|
cmd.Stderr = stderrW
|
|
err := cmd.Start()
|
|
if err != nil {
|
|
return stdout, fmt.Errorf("could not start %s command: %v", nsupdateCmd, err)
|
|
}
|
|
|
|
go func() {
|
|
io.WriteString(stdinW, nsucmd)
|
|
stdinW.Close()
|
|
}()
|
|
errBuf := new(bytes.Buffer)
|
|
go func() {
|
|
io.Copy(errBuf, stderrR)
|
|
stderrR.Close()
|
|
}()
|
|
|
|
err = cmd.Wait()
|
|
if err != nil {
|
|
return stdout, fmt.Errorf("%s did not run successfully: %v stderr: %s", nsupdateCmd, err, errBuf.String())
|
|
}
|
|
return stdout, nil
|
|
}
|
|
|
|
func extractDomainName(zone string) string {
|
|
authZone, err := util.FindZoneByFqdn(zone, util.RecursiveNameservers)
|
|
if err != nil {
|
|
klog.Errorf("could not get zone by fqdn %v", err)
|
|
return zone
|
|
}
|
|
return util.UnFqdn(authZone)
|
|
}
|