software steht so weit.

jetzt build + docker build und testen
This commit is contained in:
br committed 2026-10-02 13:25:34 +02:00
1 parent 42f0c0accb
commit ca6cdcca63
90 files changed
+10298 -480

No files matched your search

+94
View File
@@ -0,0 +1,94 @@
package agent
import (
"fmt"
"net"
"net/url"
"regexp"
"strings"
"sultan/pkg/policy"
)
// backendHost bestimmt die Adresse, unter der der Ingress die Dienste
// dieses Hosts erreicht: explizit gesetzt, sonst die IP des angegebenen
// Interfaces (z. B. wt0 für NetBird), sonst die lokale IP, über die der
// Server erreicht wird.
func backendHost(explicit, iface, serverURL string) (string, error) {
if explicit != "" {
return explicit, nil
}
if iface != "" {
return interfaceIP(iface)
}
addr, err := hostPort(serverURL)
if err != nil {
return "", err
}
// UDP-"Verbindung" sendet nichts, ermittelt aber die ausgehende Adresse.
conn, err := net.Dial("udp", addr)
if err != nil {
return "", fmt.Errorf("agent: Backend-Adresse ermitteln: %w", err)
}
defer conn.Close()
return conn.LocalAddr().(*net.UDPAddr).IP.String(), nil
}
func interfaceIP(name string) (string, error) {
ifc, err := net.InterfaceByName(name)
if err != nil {
return "", fmt.Errorf("agent: Interface %s: %w", name, err)
}
addrs, err := ifc.Addrs()
if err != nil {
return "", err
}
var v6 string
for _, a := range addrs {
ipnet, ok := a.(*net.IPNet)
if !ok {
continue
}
if ip4 := ipnet.IP.To4(); ip4 != nil {
return ip4.String(), nil
}
if v6 == "" && !ipnet.IP.IsLinkLocalUnicast() {
v6 = ipnet.IP.String()
}
}
if v6 != "" {
return v6, nil
}
return "", fmt.Errorf("agent: Interface %s hat keine nutzbare IP", name)
}
// hostPort liefert host:port der Server-URL (Default-Port 443).
func hostPort(serverURL string) (string, error) {
u, err := url.Parse(serverURL)
if err != nil || u.Hostname() == "" {
return "", fmt.Errorf("agent: Server-URL %q ungültig", serverURL)
}
if u.Port() == "" {
return net.JoinHostPort(u.Hostname(), "443"), nil
}
return u.Host, nil
}
var (
nodeIDUnsafe = regexp.MustCompile(`[^a-z0-9_-]+`)
nodeIDDashes = regexp.MustCompile(`-{2,}`)
nodeIDUnders = regexp.MustCompile(`_{2,}`)
)
// DefaultNodeID leitet aus dem Hostnamen eine gültige Knoten-ID ab
// (klein, a–z/0–9/-/_, kein "__").
func DefaultNodeID(hostname string) (string, error) {
id := nodeIDUnsafe.ReplaceAllString(strings.ToLower(strings.TrimSpace(hostname)), "-")
id = nodeIDDashes.ReplaceAllString(id, "-")
id = nodeIDUnders.ReplaceAllString(id, "_")
id = strings.Trim(id, "-_")
if !policy.ValidID(id) {
return "", fmt.Errorf("agent: aus Hostname %q lässt sich keine Knoten-ID ableiten – --node-id angeben", hostname)
}
return id, nil
}