ccl/internal/pkg/container/nsupdate.go

150 lines
3.2 KiB
Go

package container
import (
"net"
"time"
cmd "gitea.elkins.co/Networking/ccl/internal/pkg/command"
"github.com/miekg/dns"
)
func (c *Container) doReverse(rv string, dn string) error {
ptr := dns.PTR{
Hdr: dns.RR_Header{
Name: rv,
Rrtype: dns.TypePTR,
Class: dns.ClassINET,
Ttl: 7200,
},
Ptr: dn,
}
cli := new(dns.Client)
if c.TSIGName != "" {
cli.TsigSecret = map[string]string{c.TSIGName: c.TSIGKey}
}
msg := new(dns.Msg)
msg.SetQuestion(rv, dns.TypeSOA)
resp, _, err := cli.Exchange(msg, c.DnsServer)
if err != nil {
return err
}
soa := resp.Ns[0].Header().Name
// Update the reverse record
msg = new(dns.Msg)
msg.SetUpdate(soa)
msg.Ns = append(msg.Ns, &ptr)
if c.TSIGName != "" {
msg.SetTsig(c.TSIGName, dns.HmacSHA256, 300, time.Now().Unix())
}
_, _, err = cli.Exchange(msg, c.DnsServer)
if err != nil {
return err
}
return nil
}
func (c *Container) NsUpdateCommands() cmd.Set {
hostname := c.Hostname
if c.Hostname == "" {
hostname = c.Name
}
dn := dns.Fqdn(hostname + "." + c.DomainName)
cmds := []cmd.Command{}
// TODO: also iterate over c.IPv6Addresses
for i := range c.Networks {
n := &c.Networks[i]
if n.IPv6.Bool && !n.IPv6Address.IsUnspecified() {
ad := net.ParseIP(n.IPv6Address.String())
if ad != nil {
f_6 := func() error {
aaaa := dns.AAAA{
Hdr: dns.RR_Header{
Name: dn,
Rrtype: dns.TypeAAAA,
Class: dns.ClassINET,
Ttl: 7200,
},
AAAA: ad,
}
rv, err := dns.ReverseAddr(aaaa.AAAA.String())
if err != nil {
return err
}
cli := new(dns.Client)
if c.TSIGName != "" {
cli.TsigSecret = map[string]string{c.TSIGName: c.TSIGKey}
}
// Update the forward record
msg := new(dns.Msg)
msg.SetUpdate(dns.Fqdn(c.DomainName))
msg.Ns = append(msg.Ns, &aaaa)
if c.TSIGName != "" {
msg.SetTsig(c.TSIGName, dns.HmacSHA256, 300, time.Now().Unix())
}
if _, _, err = cli.Exchange(msg, c.DnsServer); err != nil {
return err
}
if err = c.doReverse(rv, dn); err != nil {
return err
}
return nil
}
cmds = append(cmds, cmd.NewFunc("nsupate6", f_6))
}
}
if !n.IPv4Address.IsUnspecified() {
ad := net.ParseIP(n.IPv4Address.String())
if ad != nil {
f_4 := func() error {
a := dns.A{
Hdr: dns.RR_Header{
Name: dn,
Rrtype: dns.TypeA,
Class: dns.ClassINET,
Ttl: 7200,
},
A: ad,
}
rv, err := dns.ReverseAddr(a.A.String())
if err != nil {
return err
}
cli := new(dns.Client)
if c.TSIGName != "" {
cli.TsigSecret = map[string]string{c.TSIGName: c.TSIGKey}
}
// Update the forward record
msg := new(dns.Msg)
msg.SetUpdate(dns.Fqdn(c.DomainName))
msg.Ns = append(msg.Ns, &a)
if c.TSIGName != "" {
msg.SetTsig(c.TSIGName, dns.HmacSHA256, 300, time.Now().Unix())
}
if _, _, err = cli.Exchange(msg, c.DnsServer); err != nil {
return err
}
if err = c.doReverse(rv, dn); err != nil {
return err
}
return nil
}
cmds = append(cmds, cmd.NewFunc("nsupate4", f_4))
}
}
}
return c.newCommandSet("NSUPDATE", cmds)
}