...
1
16
17 package util
18
19 import (
20 "fmt"
21 "net"
22
23 v1 "k8s.io/api/core/v1"
24 netutils "k8s.io/utils/net"
25 )
26
27
28 type NodePortAddresses struct {
29 cidrStrings []string
30
31 cidrs []*net.IPNet
32 containsIPv4Loopback bool
33 matchAll bool
34 }
35
36
37 var ipv4LoopbackStart = net.IPv4(127, 0, 0, 0)
38
39
40
41
42
43
44
45 func NewNodePortAddresses(family v1.IPFamily, cidrStrings []string, primaryIP net.IP) *NodePortAddresses {
46 npa := &NodePortAddresses{}
47
48
49 for _, str := range cidrStrings {
50 if (family == v1.IPv4Protocol) == netutils.IsIPv4CIDRString(str) {
51 npa.cidrStrings = append(npa.cidrStrings, str)
52 }
53 }
54 if len(npa.cidrStrings) == 0 {
55 if primaryIP == nil {
56 if family == v1.IPv4Protocol {
57 npa.cidrStrings = []string{IPv4ZeroCIDR}
58 } else {
59 npa.cidrStrings = []string{IPv6ZeroCIDR}
60 }
61 } else {
62 if family == v1.IPv4Protocol {
63 npa.cidrStrings = []string{fmt.Sprintf("%s/32", primaryIP.String())}
64 } else {
65 npa.cidrStrings = []string{fmt.Sprintf("%s/128", primaryIP.String())}
66 }
67 }
68 }
69
70
71 for _, str := range npa.cidrStrings {
72 _, cidr, _ := netutils.ParseCIDRSloppy(str)
73 if netutils.IsIPv4CIDR(cidr) {
74 if cidr.IP.IsLoopback() || cidr.Contains(ipv4LoopbackStart) {
75 npa.containsIPv4Loopback = true
76 }
77 }
78
79 if IsZeroCIDR(str) {
80
81 npa.cidrs = []*net.IPNet{cidr}
82 npa.matchAll = true
83 break
84 }
85
86 npa.cidrs = append(npa.cidrs, cidr)
87 }
88
89 return npa
90 }
91
92 func (npa *NodePortAddresses) String() string {
93 return fmt.Sprintf("%v", npa.cidrStrings)
94 }
95
96
97 func (npa *NodePortAddresses) MatchAll() bool {
98 return npa.matchAll
99 }
100
101
102
103
104 func (npa *NodePortAddresses) GetNodeIPs(nw NetworkInterfacer) ([]net.IP, error) {
105 addrs, err := nw.InterfaceAddrs()
106 if err != nil {
107 return nil, fmt.Errorf("error listing all interfaceAddrs from host, error: %v", err)
108 }
109
110
111 addresses := make(map[string]net.IP)
112 for _, cidr := range npa.cidrs {
113 for _, addr := range addrs {
114 var ip net.IP
115
116 switch v := addr.(type) {
117 case *net.IPAddr:
118 ip = v.IP
119 case *net.IPNet:
120 ip = v.IP
121 default:
122 continue
123 }
124
125 if cidr.Contains(ip) {
126 addresses[ip.String()] = ip
127 }
128 }
129 }
130
131 ips := make([]net.IP, 0, len(addresses))
132 for _, ip := range addresses {
133 ips = append(ips, ip)
134 }
135
136 return ips, nil
137 }
138
139
140 func (npa *NodePortAddresses) ContainsIPv4Loopback() bool {
141 return npa.containsIPv4Loopback
142 }
143
View as plain text