package envx import ( "net" "os" "strconv" "strings" ) func String(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback } func Int(key string, fallback int) int { if v := os.Getenv(key); v != "" { if i, err := strconv.Atoi(v); err == nil { return i } } return fallback } func LocalIP() string { for _, key := range []string{"nacos_bindIp", "NACOS_BIND_IP", "LOCAL_IP", "BIND_IP"} { if ip := validIPv4(os.Getenv(key)); ip != "" { return ip } } if ip := hostnameIP(); ip != "" { return ip } if ip := interfaceIP(); ip != "" { return ip } if ip := outboundIP(); ip != "" { return ip } return "127.0.0.1" } func hostnameIP() string { hostname, err := os.Hostname() if err != nil || hostname == "" { return "" } addrs, err := net.LookupIP(hostname) if err != nil { return "" } for _, addr := range addrs { if ip := validIPv4(addr.String()); ip != "" { return ip } } return "" } func interfaceIP() string { ifaces, err := net.Interfaces() if err != nil { return "" } bestIP := "" bestScore := -1 for _, iface := range ifaces { if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 { continue } addrs, err := iface.Addrs() if err != nil { continue } for _, addr := range addrs { ipNet, ok := addr.(*net.IPNet) if !ok { continue } ip := validIPv4(ipNet.IP.String()) if ip == "" { continue } score := interfaceScore(iface.Name) if score > bestScore { bestIP = ip bestScore = score } } } return bestIP } func interfaceScore(name string) int { name = strings.ToLower(name) switch { case name == "eth0": return 100 case strings.HasPrefix(name, "eth"): return 90 case strings.HasPrefix(name, "en"), strings.HasPrefix(name, "wl"): return 80 case strings.Contains(name, "docker"), strings.HasPrefix(name, "br-"), strings.HasPrefix(name, "veth"): return 10 default: return 50 } } func outboundIP() string { conn, err := net.Dial("udp", "8.8.8.8:80") if err == nil { defer conn.Close() if addr, ok := conn.LocalAddr().(*net.UDPAddr); ok { return validIPv4(addr.IP.String()) } } return "" } func validIPv4(value string) string { ip := net.ParseIP(strings.TrimSpace(value)).To4() if ip == nil || ip.IsLoopback() || ip.IsUnspecified() || ip.IsLinkLocalUnicast() { return "" } return ip.String() }