clitools: Added ConfigureDNS
This commit is contained in:
@@ -4,16 +4,19 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
system "undecided.project/monok8s/pkg/system"
|
||||
"k8s.io/klog/v2"
|
||||
system "undecided.project/monok8s/pkg/system"
|
||||
)
|
||||
|
||||
type NetworkConfig struct {
|
||||
MgmtIface string
|
||||
MgmtAddress string
|
||||
MgmtGateway string
|
||||
MgmtIface string
|
||||
MgmtAddress string
|
||||
MgmtGateway string
|
||||
DNSNameservers []string
|
||||
DNSSearchDomains []string
|
||||
}
|
||||
|
||||
func ConfigureMgmtInterface(cfg NetworkConfig) Step {
|
||||
@@ -24,18 +27,31 @@ func ConfigureMgmtInterface(cfg NetworkConfig) Step {
|
||||
if strings.TrimSpace(cfg.MgmtAddress) == "" {
|
||||
return fmt.Errorf("mgmt address is required")
|
||||
}
|
||||
ip, ipNet, err := net.ParseCIDR(cfg.MgmtAddress)
|
||||
|
||||
ip, ipNet, err := net.ParseCIDR(strings.TrimSpace(cfg.MgmtAddress))
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid mgmt address %q: %w", cfg.MgmtAddress, err)
|
||||
}
|
||||
wantIP := ip.String()
|
||||
if gw := strings.TrimSpace(cfg.MgmtGateway); gw != "" && net.ParseIP(gw) == nil {
|
||||
return fmt.Errorf("invalid mgmt gateway %q", gw)
|
||||
|
||||
ip4 := ip.To4()
|
||||
if ip4 == nil {
|
||||
return fmt.Errorf("mgmt address must be IPv4: %q", cfg.MgmtAddress)
|
||||
}
|
||||
|
||||
wantIP := ip4.String()
|
||||
wantCIDR := fmt.Sprintf("%s/%d", wantIP, maskSize(ipNet.Mask))
|
||||
|
||||
if gw := strings.TrimSpace(cfg.MgmtGateway); gw != "" {
|
||||
gwIP := net.ParseIP(gw)
|
||||
if gwIP == nil || gwIP.To4() == nil {
|
||||
return fmt.Errorf("invalid mgmt gateway %q", gw)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := nctx.System.Run(ctx, "ip", "link", "show", "dev", cfg.MgmtIface); err != nil {
|
||||
return fmt.Errorf("interface not found: %s: %w", cfg.MgmtIface, err)
|
||||
}
|
||||
|
||||
if _, err := nctx.System.Run(ctx, "ip", "link", "set", "dev", cfg.MgmtIface, "up"); err != nil {
|
||||
return fmt.Errorf("failed to bring up interface %s: %w", cfg.MgmtIface, err)
|
||||
}
|
||||
@@ -44,11 +60,12 @@ func ConfigureMgmtInterface(cfg NetworkConfig) Step {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed checking existing address on %s: %w", cfg.MgmtIface, err)
|
||||
}
|
||||
|
||||
if hasAddr {
|
||||
klog.Infof("address already present on %s: %s", cfg.MgmtIface, cfg.MgmtAddress)
|
||||
klog.Infof("address already present on %s: %s", cfg.MgmtIface, wantCIDR)
|
||||
} else {
|
||||
if _, err := nctx.System.Run(ctx, "ip", "addr", "add", ipNet.String(), "dev", cfg.MgmtIface); err != nil {
|
||||
return fmt.Errorf("failed assigning %s to %s: %w", ipNet.String(), cfg.MgmtIface, err)
|
||||
if _, err := nctx.System.Run(ctx, "ip", "addr", "add", wantCIDR, "dev", cfg.MgmtIface); err != nil {
|
||||
return fmt.Errorf("failed assigning %s to %s: %w", wantCIDR, cfg.MgmtIface, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,17 +74,88 @@ func ConfigureMgmtInterface(cfg NetworkConfig) Step {
|
||||
return fmt.Errorf("failed setting default route via %s dev %s: %w", gw, cfg.MgmtIface, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func maskSize(m net.IPMask) int {
|
||||
ones, _ := m.Size()
|
||||
return ones
|
||||
}
|
||||
|
||||
func EnsureIPForward(ctx context.Context, n *NodeContext) error {
|
||||
return system.EnsureSysctl(ctx, n.System, "net.ipv4.ip_forward", "1")
|
||||
}
|
||||
|
||||
func ConfigureDNS(context.Context, *NodeContext) error {
|
||||
klog.Info("configure_dns: TODO implement resolv.conf rendering")
|
||||
return nil
|
||||
func ConfigureDNS(cfg NetworkConfig) Step {
|
||||
return func(context.Context, *NodeContext) error {
|
||||
|
||||
if len(cfg.DNSNameservers) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var nameservers []string
|
||||
for _, ns := range cfg.DNSNameservers {
|
||||
ns = strings.TrimSpace(ns)
|
||||
if ns == "" {
|
||||
continue
|
||||
}
|
||||
if ip := net.ParseIP(ns); ip == nil {
|
||||
return fmt.Errorf("invalid DNS nameserver %q", ns)
|
||||
}
|
||||
nameservers = append(nameservers, ns)
|
||||
}
|
||||
if len(nameservers) == 0 {
|
||||
return fmt.Errorf("DNSNameservers is set but no valid nameservers were parsed")
|
||||
}
|
||||
|
||||
var searchDomains []string
|
||||
for _, d := range cfg.DNSSearchDomains {
|
||||
d = strings.TrimSpace(d)
|
||||
if d == "" {
|
||||
continue
|
||||
}
|
||||
searchDomains = append(searchDomains, d)
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
if len(searchDomains) > 0 {
|
||||
b.WriteString("search ")
|
||||
b.WriteString(strings.Join(searchDomains, " "))
|
||||
b.WriteByte('\n')
|
||||
}
|
||||
for _, ns := range nameservers {
|
||||
b.WriteString("nameserver ")
|
||||
b.WriteString(ns)
|
||||
b.WriteByte('\n')
|
||||
}
|
||||
b.WriteString("options timeout:2 attempts:3\n")
|
||||
|
||||
const (
|
||||
resolvDir = "/etc"
|
||||
tmpPath = "/etc/resolv.conf.monok8s.tmp"
|
||||
resolvPath = "/etc/resolv.conf"
|
||||
)
|
||||
|
||||
if err := os.MkdirAll(resolvDir, 0o755); err != nil {
|
||||
klog.Warningf("failed to create %s for DNS config: %v; leaving %s unchanged", resolvDir, err, resolvPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := os.WriteFile(tmpPath, []byte(b.String()), 0o644); err != nil {
|
||||
klog.Warningf("failed to write temporary DNS config %s: %v; leaving %s unchanged", tmpPath, err, resolvPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := os.Rename(tmpPath, resolvPath); err != nil {
|
||||
_ = os.Remove(tmpPath)
|
||||
klog.Warningf("failed to install DNS config at %s: %v; leaving existing DNS config unchanged", resolvPath, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func interfaceHasIPv4(ctx context.Context, nctx *NodeContext, iface, wantIP string) (bool, error) {
|
||||
|
||||
Reference in New Issue
Block a user