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  }