892d849740
if a Machine is Inactive, it won't be included on the DNS aliases for the zone or it's regions. v2: - Machine.Active() renamed to Machine.IsActive() Signed-off-by: Alejandro Mery <amery@jpi.io>
194 lines
3.9 KiB
Go
194 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"net/netip"
|
|
"os"
|
|
"time"
|
|
|
|
"darvaza.org/core"
|
|
"github.com/spf13/cobra"
|
|
|
|
"git.jpi.io/amery/jpictl/pkg/cluster"
|
|
"git.jpi.io/amery/jpictl/pkg/dns"
|
|
)
|
|
|
|
const (
|
|
// DNSSyncTimeout specifies how long are we willing to wait for a DNS
|
|
// synchronization
|
|
DNSSyncTimeout = 10 * time.Second
|
|
)
|
|
|
|
func newDNSManager(m *cluster.Cluster, provider dns.Provider) (*dns.Manager, error) {
|
|
domain := m.Domain
|
|
if m.Name != "" {
|
|
domain = m.Name + "." + domain
|
|
}
|
|
|
|
mgr, err := dns.NewManager(dns.WithDomain(domain), dns.WithLogger(log))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if provider != nil {
|
|
// set provider only if specified
|
|
err = dns.WithProvider(provider)(mgr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if err := populateDNSManager(mgr, m); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return mgr, nil
|
|
}
|
|
|
|
func populateDNSManager(mgr *dns.Manager, m *cluster.Cluster) error {
|
|
var err error
|
|
|
|
ctx := context.TODO()
|
|
|
|
m.ForEachZone(func(z *cluster.Zone) bool {
|
|
z.ForEachMachine(func(p *cluster.Machine) bool {
|
|
err = mgr.AddHost(ctx, z.Name, p.ID, p.IsActive(), p.PublicAddresses...)
|
|
return err != nil
|
|
})
|
|
|
|
return err != nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
m.ForEachRegion(func(r *cluster.Region) bool {
|
|
r.ForEachZone(func(z *cluster.Zone) bool {
|
|
err = mgr.AddRegion(ctx, r.Name, z.Name)
|
|
return err != nil
|
|
})
|
|
|
|
return err != nil
|
|
})
|
|
|
|
return err
|
|
}
|
|
|
|
// revive:disable:flag-parameter
|
|
func newDNSManagerCommand(_ *cobra.Command,
|
|
resolve bool, withCredentials bool) (*dns.Manager, error) {
|
|
// revive:enable:flag-parameter
|
|
var cred dns.Provider
|
|
|
|
if withCredentials {
|
|
var err error
|
|
|
|
cred, err = dns.DefaultDNSProvider()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
m, err := cfg.LoadZones(resolve)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return newDNSManager(m, cred)
|
|
}
|
|
|
|
// Command
|
|
var dnsCmd = &cobra.Command{
|
|
Use: "dns",
|
|
}
|
|
|
|
var dnsWriteCmd = &cobra.Command{
|
|
Use: "write",
|
|
Short: "dns write generates public DNS records",
|
|
PreRun: setVerbosity,
|
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
mgr, err := newDNSManagerCommand(cmd, true, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = mgr.WriteTo(os.Stdout)
|
|
return err
|
|
},
|
|
}
|
|
|
|
var dnsSyncCmd = &cobra.Command{
|
|
Use: "sync",
|
|
Short: "dns sync updates public DNS records",
|
|
PreRun: setVerbosity,
|
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
mgr, err := newDNSManagerCommand(cmd, true, true)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), DNSSyncTimeout)
|
|
defer cancel()
|
|
|
|
return mgr.Sync(ctx)
|
|
},
|
|
}
|
|
|
|
var dnsShowCmd = &cobra.Command{
|
|
Use: "show [<name>...]",
|
|
Short: "dns show lists entries on DNS for our domain",
|
|
PreRun: setVerbosity,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
mgr, err := newDNSManagerCommand(cmd, true, true)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), DNSSyncTimeout)
|
|
defer cancel()
|
|
|
|
return mgr.Show(ctx, args...)
|
|
},
|
|
}
|
|
|
|
var dnsAddCmd = &cobra.Command{
|
|
Use: "add <name> <address..>",
|
|
Short: "dns add registers a new machine on the public DNS",
|
|
Args: cobra.MinimumNArgs(2),
|
|
PreRun: setVerbosity,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
var addrs []netip.Addr
|
|
|
|
for _, s := range args[1:] {
|
|
addr, err := core.ParseAddr(s)
|
|
switch {
|
|
case err != nil:
|
|
return core.Wrap(err, s)
|
|
case !addr.IsValid(), addr.IsUnspecified(), addr.IsPrivate(), addr.IsMulticast():
|
|
return core.Wrap(core.ErrInvalid, s)
|
|
default:
|
|
addrs = append(addrs, addr)
|
|
}
|
|
}
|
|
|
|
mgr, err := newDNSManagerCommand(cmd, true, true)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), DNSSyncTimeout)
|
|
defer cancel()
|
|
|
|
return mgr.Add(ctx, args[0], addrs...)
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(dnsCmd)
|
|
|
|
dnsCmd.AddCommand(dnsWriteCmd)
|
|
dnsCmd.AddCommand(dnsSyncCmd)
|
|
dnsCmd.AddCommand(dnsShowCmd)
|
|
dnsCmd.AddCommand(dnsAddCmd)
|
|
}
|