123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- package util
- import (
- "context"
- "errors"
- "fmt"
- "net"
- "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/types"
- "k8s.io/apimachinery/pkg/util/sets"
- "k8s.io/client-go/tools/record"
- helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
- utilnet "k8s.io/utils/net"
- "k8s.io/klog"
- )
- const (
-
- IPv4ZeroCIDR = "0.0.0.0/0"
-
- IPv6ZeroCIDR = "::/0"
- )
- var (
-
- ErrAddressNotAllowed = errors.New("address not allowed")
-
- ErrNoAddresses = errors.New("No addresses for hostname")
- )
- func IsZeroCIDR(cidr string) bool {
- if cidr == IPv4ZeroCIDR || cidr == IPv6ZeroCIDR {
- return true
- }
- return false
- }
- func IsProxyableIP(ip string) error {
- netIP := net.ParseIP(ip)
- if netIP == nil {
- return ErrAddressNotAllowed
- }
- return isProxyableIP(netIP)
- }
- func isProxyableIP(ip net.IP) error {
- if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsInterfaceLocalMulticast() {
- return ErrAddressNotAllowed
- }
- return nil
- }
- type Resolver interface {
- LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, error)
- }
- func IsProxyableHostname(ctx context.Context, resolv Resolver, hostname string) error {
- resp, err := resolv.LookupIPAddr(ctx, hostname)
- if err != nil {
- return err
- }
- if len(resp) == 0 {
- return ErrNoAddresses
- }
- for _, host := range resp {
- if err := isProxyableIP(host.IP); err != nil {
- return err
- }
- }
- return nil
- }
- func IsLocalIP(ip string) (bool, error) {
- addrs, err := net.InterfaceAddrs()
- if err != nil {
- return false, err
- }
- for i := range addrs {
- intf, _, err := net.ParseCIDR(addrs[i].String())
- if err != nil {
- return false, err
- }
- if net.ParseIP(ip).Equal(intf) {
- return true, nil
- }
- }
- return false, nil
- }
- func ShouldSkipService(svcName types.NamespacedName, service *v1.Service) bool {
-
- if !helper.IsServiceIPSet(service) {
- klog.V(3).Infof("Skipping service %s due to clusterIP = %q", svcName, service.Spec.ClusterIP)
- return true
- }
-
- if service.Spec.Type == v1.ServiceTypeExternalName {
- klog.V(3).Infof("Skipping service %s due to Type=ExternalName", svcName)
- return true
- }
- return false
- }
- func GetNodeAddresses(cidrs []string, nw NetworkInterfacer) (sets.String, error) {
- uniqueAddressList := sets.NewString()
- if len(cidrs) == 0 {
- uniqueAddressList.Insert(IPv4ZeroCIDR)
- uniqueAddressList.Insert(IPv6ZeroCIDR)
- return uniqueAddressList, nil
- }
-
- for _, cidr := range cidrs {
- if IsZeroCIDR(cidr) {
- uniqueAddressList.Insert(cidr)
- }
- }
-
- for _, cidr := range cidrs {
- if IsZeroCIDR(cidr) {
- continue
- }
- _, ipNet, _ := net.ParseCIDR(cidr)
- itfs, err := nw.Interfaces()
- if err != nil {
- return nil, fmt.Errorf("error listing all interfaces from host, error: %v", err)
- }
- for _, itf := range itfs {
- addrs, err := nw.Addrs(&itf)
- if err != nil {
- return nil, fmt.Errorf("error getting address from interface %s, error: %v", itf.Name, err)
- }
- for _, addr := range addrs {
- if addr == nil {
- continue
- }
- ip, _, err := net.ParseCIDR(addr.String())
- if err != nil {
- return nil, fmt.Errorf("error parsing CIDR for interface %s, error: %v", itf.Name, err)
- }
- if ipNet.Contains(ip) {
- if utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv6ZeroCIDR) {
- uniqueAddressList.Insert(ip.String())
- }
- if !utilnet.IsIPv6(ip) && !uniqueAddressList.Has(IPv4ZeroCIDR) {
- uniqueAddressList.Insert(ip.String())
- }
- }
- }
- }
- }
- return uniqueAddressList, nil
- }
- func LogAndEmitIncorrectIPVersionEvent(recorder record.EventRecorder, fieldName, fieldValue, svcNamespace, svcName string, svcUID types.UID) {
- errMsg := fmt.Sprintf("%s in %s has incorrect IP version", fieldValue, fieldName)
- klog.Errorf("%s (service %s/%s).", errMsg, svcNamespace, svcName)
- if recorder != nil {
- recorder.Eventf(
- &v1.ObjectReference{
- Kind: "Service",
- Name: svcName,
- Namespace: svcNamespace,
- UID: svcUID,
- }, v1.EventTypeWarning, "KubeProxyIncorrectIPVersion", errMsg)
- }
- }
- func FilterIncorrectIPVersion(ipStrings []string, isIPv6Mode bool) ([]string, []string) {
- return filterWithCondition(ipStrings, isIPv6Mode, utilnet.IsIPv6String)
- }
- func FilterIncorrectCIDRVersion(ipStrings []string, isIPv6Mode bool) ([]string, []string) {
- return filterWithCondition(ipStrings, isIPv6Mode, utilnet.IsIPv6CIDRString)
- }
- func filterWithCondition(strs []string, expectedCondition bool, conditionFunc func(string) bool) ([]string, []string) {
- var corrects, incorrects []string
- for _, str := range strs {
- if conditionFunc(str) != expectedCondition {
- incorrects = append(incorrects, str)
- } else {
- corrects = append(corrects, str)
- }
- }
- return corrects, incorrects
- }
- func AppendPortIfNeeded(addr string, port int32) string {
-
- if _, _, err := net.SplitHostPort(addr); err == nil {
- return addr
- }
-
- ip := net.ParseIP(addr)
- if ip == nil {
- return addr
- }
-
- if ip.To4() != nil {
- return fmt.Sprintf("%s:%d", addr, port)
- }
- return fmt.Sprintf("[%s]:%d", addr, port)
- }
|