mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-06 18:54:06 +00:00
pkg/proxy: refactor npa.GetNodeIPs
Signed-off-by: Daman Arora <aroradaman@gmail.com>
This commit is contained in:
parent
11c0683c32
commit
a3ad527ffd
@ -94,38 +94,7 @@ func (npa *NodePortAddresses) MatchAll() bool {
|
|||||||
// IPs are found, it returns an empty list.
|
// IPs are found, it returns an empty list.
|
||||||
// NetworkInterfacer is injected for test purpose.
|
// NetworkInterfacer is injected for test purpose.
|
||||||
func (npa *NodePortAddresses) GetNodeIPs(nw NetworkInterfacer) ([]net.IP, error) {
|
func (npa *NodePortAddresses) GetNodeIPs(nw NetworkInterfacer) ([]net.IP, error) {
|
||||||
addrs, err := nw.InterfaceAddrs()
|
return FilterInterfaceAddrsByCIDRs(nw, npa.cidrs)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error listing all interfaceAddrs from host, error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use a map to dedup matches
|
|
||||||
addresses := make(map[string]net.IP)
|
|
||||||
for _, cidr := range npa.cidrs {
|
|
||||||
for _, addr := range addrs {
|
|
||||||
var ip net.IP
|
|
||||||
// nw.InterfaceAddrs may return net.IPAddr or net.IPNet on windows, and it will return net.IPNet on linux.
|
|
||||||
switch v := addr.(type) {
|
|
||||||
case *net.IPAddr:
|
|
||||||
ip = v.IP
|
|
||||||
case *net.IPNet:
|
|
||||||
ip = v.IP
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if cidr.Contains(ip) {
|
|
||||||
addresses[ip.String()] = ip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ips := make([]net.IP, 0, len(addresses))
|
|
||||||
for _, ip := range addresses {
|
|
||||||
ips = append(ips, ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ips, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainsIPv4Loopback returns true if npa's CIDRs contain an IPv4 loopback address.
|
// ContainsIPv4Loopback returns true if npa's CIDRs contain an IPv4 loopback address.
|
||||||
|
@ -241,3 +241,49 @@ func IsVIPMode(ing v1.LoadBalancerIngress) bool {
|
|||||||
}
|
}
|
||||||
return *ing.IPMode == v1.LoadBalancerIPModeVIP
|
return *ing.IPMode == v1.LoadBalancerIPModeVIP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilterInterfaceAddrsByCIDRs filters the IP addresses of the provided NetworkInterfacer,
|
||||||
|
// returning only those that belong to any of the CIDRs specified in the given list.
|
||||||
|
func FilterInterfaceAddrsByCIDRs(nw NetworkInterfacer, cidrs []*net.IPNet) ([]net.IP, error) {
|
||||||
|
addrs, err := nw.InterfaceAddrs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error listing all interfaceAddrs from host, error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use a map to dedup matches
|
||||||
|
addresses := make(map[string]net.IP)
|
||||||
|
for _, cidr := range cidrs {
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var ip net.IP
|
||||||
|
// nw.InterfaceAddrs may return net.IPAddr or net.IPNet on windows, and it will return net.IPNet on linux.
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPAddr:
|
||||||
|
ip = v.IP
|
||||||
|
case *net.IPNet:
|
||||||
|
ip = v.IP
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if cidr.Contains(ip) {
|
||||||
|
addresses[ip.String()] = ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ips := make([]net.IP, 0, len(addresses))
|
||||||
|
for _, ip := range addresses {
|
||||||
|
ips = append(ips, ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ips, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterInterfaceAddrsByCIDRStrings is a wrapper around FilterInterfaceAddrsByCIDRs which accepts CIDRs as list of strings.
|
||||||
|
func FilterInterfaceAddrsByCIDRStrings(nw NetworkInterfacer, cidrStrings []string) ([]net.IP, error) {
|
||||||
|
cidrs, err := netutils.ParseCIDRs(cidrStrings)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return FilterInterfaceAddrsByCIDRs(nw, cidrs)
|
||||||
|
}
|
||||||
|
@ -21,9 +21,12 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
proxyutiltest "k8s.io/kubernetes/pkg/proxy/util/testing"
|
||||||
netutils "k8s.io/utils/net"
|
netutils "k8s.io/utils/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -703,3 +706,58 @@ func TestIsZeroCIDR(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFilterInterfaceAddrsByCIDRs(t *testing.T) {
|
||||||
|
networkInterfacer := proxyutiltest.NewFakeNetwork()
|
||||||
|
var itf net.Interface
|
||||||
|
var addrs []net.Addr
|
||||||
|
itf = net.Interface{Index: 0, MTU: 0, Name: "eth1", HardwareAddr: nil, Flags: 0}
|
||||||
|
addrs = []net.Addr{
|
||||||
|
&net.IPNet{IP: netutils.ParseIPSloppy("10.10.10.10"), Mask: net.CIDRMask(24, 32)},
|
||||||
|
&net.IPNet{IP: netutils.ParseIPSloppy("2001:db8::1"), Mask: net.CIDRMask(64, 128)},
|
||||||
|
}
|
||||||
|
networkInterfacer.AddInterfaceAddr(&itf, addrs)
|
||||||
|
|
||||||
|
itf = net.Interface{Index: 0, MTU: 0, Name: "eth2", HardwareAddr: nil, Flags: 0}
|
||||||
|
addrs = []net.Addr{
|
||||||
|
&net.IPNet{IP: netutils.ParseIPSloppy("192.168.0.2"), Mask: net.CIDRMask(24, 32)},
|
||||||
|
&net.IPNet{IP: netutils.ParseIPSloppy("fd00:4321::2"), Mask: net.CIDRMask(64, 128)},
|
||||||
|
}
|
||||||
|
networkInterfacer.AddInterfaceAddr(&itf, addrs)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
cidrStrings []string
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ipv4",
|
||||||
|
cidrStrings: []string{"192.168.0.0/24"},
|
||||||
|
expected: []string{"192.168.0.2"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ipv6",
|
||||||
|
cidrStrings: []string{"fd00:4321::/64"},
|
||||||
|
expected: []string{"fd00:4321::2"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "dual stack",
|
||||||
|
cidrStrings: []string{"10.10.0.0/16", "2001:db8::/64"},
|
||||||
|
expected: []string{"10.10.10.10", "2001:db8::1"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
cidrs, err := netutils.ParseCIDRs(tc.cidrStrings)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
ips, err := FilterInterfaceAddrsByCIDRs(networkInterfacer, cidrs)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var expected []net.IP
|
||||||
|
for i := range tc.expected {
|
||||||
|
expected = append(expected, netutils.ParseIPSloppy(tc.expected[i]))
|
||||||
|
}
|
||||||
|
require.Equal(t, expected, ips)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user