github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/util/net.go (about) 1 package util 2 3 import ( 4 "fmt" 5 "net" 6 "strings" 7 8 "github.com/go-kit/log/level" 9 10 util_log "github.com/grafana/loki/pkg/util/log" 11 ) 12 13 // GetFirstAddressOf returns the first IPv4 address of the supplied interface names, omitting any 169.254.x.x automatic private IPs if possible. 14 func GetFirstAddressOf(names []string) (string, error) { 15 var ipAddr string 16 for _, name := range names { 17 inf, err := net.InterfaceByName(name) 18 if err != nil { 19 level.Warn(util_log.Logger).Log("msg", "error getting interface", "inf", name, "err", err) 20 continue 21 } 22 addrs, err := inf.Addrs() 23 if err != nil { 24 level.Warn(util_log.Logger).Log("msg", "error getting addresses for interface", "inf", name, "err", err) 25 continue 26 } 27 if len(addrs) <= 0 { 28 level.Warn(util_log.Logger).Log("msg", "no addresses found for interface", "inf", name, "err", err) 29 continue 30 } 31 if ip := filterIPs(addrs); ip != "" { 32 ipAddr = ip 33 } 34 if strings.HasPrefix(ipAddr, `169.254.`) || ipAddr == "" { 35 continue 36 } 37 return ipAddr, nil 38 } 39 if ipAddr == "" { 40 return "", fmt.Errorf("no address found for %s", names) 41 } 42 if strings.HasPrefix(ipAddr, `169.254.`) { 43 level.Warn(util_log.Logger).Log("msg", "using automatic private ip", "address", ipAddr) 44 } 45 return ipAddr, nil 46 } 47 48 // filterIPs attempts to return the first non automatic private IP (APIPA / 169.254.x.x) if possible, only returning APIPA if available and no other valid IP is found. 49 func filterIPs(addrs []net.Addr) string { 50 var ipAddr string 51 for _, addr := range addrs { 52 if v, ok := addr.(*net.IPNet); ok { 53 if ip := v.IP.To4(); ip != nil { 54 ipAddr = v.IP.String() 55 if !strings.HasPrefix(ipAddr, `169.254.`) { 56 return ipAddr 57 } 58 } 59 } 60 } 61 return ipAddr 62 }