初始版本

This commit is contained in:
2026-05-06 14:53:45 +08:00
commit b759ceb1c6
10 changed files with 814 additions and 0 deletions

128
envx/envx.go Normal file
View File

@@ -0,0 +1,128 @@
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()
}