1
2
3
4
19
20 package conntrack
21
22 import (
23 "net"
24 "reflect"
25 "testing"
26
27 v1 "k8s.io/api/core/v1"
28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29 "k8s.io/apimachinery/pkg/types"
30 "k8s.io/apimachinery/pkg/util/sets"
31 "k8s.io/kubernetes/pkg/proxy"
32 )
33
34 const (
35 testClusterIP = "172.30.1.1"
36 testExternalIP = "192.168.99.100"
37 testLoadBalancerIP = "1.2.3.4"
38
39 testEndpointIP = "10.240.0.4"
40
41 testPort = 53
42 testNodePort = 5353
43 testEndpointPort = "5300"
44 )
45
46 func TestCleanStaleEntries(t *testing.T) {
47
48
49
50
51
52
53 sct := proxy.NewServiceChangeTracker(nil, v1.IPv4Protocol, nil, nil)
54 svc := &v1.Service{
55 ObjectMeta: metav1.ObjectMeta{
56 Name: "cleanup-test",
57 Namespace: "test",
58 },
59 Spec: v1.ServiceSpec{
60 ClusterIP: testClusterIP,
61 ExternalIPs: []string{testExternalIP},
62 Ports: []v1.ServicePort{
63 {
64 Name: "dns-tcp",
65 Port: testPort,
66 Protocol: v1.ProtocolTCP,
67 },
68 {
69 Name: "dns-udp",
70 Port: testPort,
71 NodePort: testNodePort,
72 Protocol: v1.ProtocolUDP,
73 },
74 },
75 },
76 Status: v1.ServiceStatus{
77 LoadBalancer: v1.LoadBalancerStatus{
78 Ingress: []v1.LoadBalancerIngress{{
79 IP: testLoadBalancerIP,
80 }},
81 },
82 },
83 }
84 sct.Update(nil, svc)
85
86 svcPortMap := make(proxy.ServicePortMap)
87 _ = svcPortMap.Update(sct)
88
89
90
91
92
93 tcpPortName := proxy.ServicePortName{
94 NamespacedName: types.NamespacedName{
95 Namespace: svc.Namespace,
96 Name: svc.Name,
97 },
98 Port: svc.Spec.Ports[0].Name,
99 Protocol: svc.Spec.Ports[0].Protocol,
100 }
101
102 udpPortName := proxy.ServicePortName{
103 NamespacedName: types.NamespacedName{
104 Namespace: svc.Namespace,
105 Name: svc.Name,
106 },
107 Port: svc.Spec.Ports[1].Name,
108 Protocol: svc.Spec.Ports[1].Protocol,
109 }
110
111 unknownPortName := udpPortName
112 unknownPortName.Namespace = "unknown"
113
114
115 if len(svcPortMap) != 2 {
116 t.Fatalf("expected svcPortMap to have 2 entries, got %+v", svcPortMap)
117 }
118 servicePort := svcPortMap[tcpPortName]
119 if servicePort == nil || servicePort.String() != "172.30.1.1:53/TCP" {
120 t.Fatalf("expected svcPortMap[%q] to be \"172.30.1.1:53/TCP\", got %q", tcpPortName.String(), servicePort.String())
121 }
122 servicePort = svcPortMap[udpPortName]
123 if servicePort == nil || servicePort.String() != "172.30.1.1:53/UDP" {
124 t.Fatalf("expected svcPortMap[%q] to be \"172.30.1.1:53/UDP\", got %q", udpPortName.String(), servicePort.String())
125 }
126
127 testCases := []struct {
128 description string
129
130 serviceUpdates proxy.UpdateServiceMapResult
131 endpointsUpdates proxy.UpdateEndpointsMapResult
132
133 result FakeInterface
134 }{
135 {
136 description: "DeletedUDPClusterIPs clears entries for given clusterIPs (only)",
137
138 serviceUpdates: proxy.UpdateServiceMapResult{
139
140
141 DeletedUDPClusterIPs: sets.New("172.30.99.99"),
142 },
143 endpointsUpdates: proxy.UpdateEndpointsMapResult{},
144
145 result: FakeInterface{
146 ClearedIPs: sets.New("172.30.99.99"),
147
148 ClearedPorts: sets.New[int](),
149 ClearedNATs: map[string]string{},
150 ClearedPortNATs: map[int]string{},
151 },
152 },
153 {
154 description: "DeletedUDPEndpoints clears NAT entries for all IPs and NodePorts",
155
156 serviceUpdates: proxy.UpdateServiceMapResult{
157 DeletedUDPClusterIPs: sets.New[string](),
158 },
159 endpointsUpdates: proxy.UpdateEndpointsMapResult{
160 DeletedUDPEndpoints: []proxy.ServiceEndpoint{{
161 Endpoint: net.JoinHostPort(testEndpointIP, testEndpointPort),
162 ServicePortName: udpPortName,
163 }},
164 },
165
166 result: FakeInterface{
167 ClearedIPs: sets.New[string](),
168 ClearedPorts: sets.New[int](),
169
170 ClearedNATs: map[string]string{
171 testClusterIP: testEndpointIP,
172 testExternalIP: testEndpointIP,
173 testLoadBalancerIP: testEndpointIP,
174 },
175 ClearedPortNATs: map[int]string{
176 testNodePort: testEndpointIP,
177 },
178 },
179 },
180 {
181 description: "NewlyActiveUDPServices clears entries for all IPs and NodePorts",
182
183 serviceUpdates: proxy.UpdateServiceMapResult{
184 DeletedUDPClusterIPs: sets.New[string](),
185 },
186 endpointsUpdates: proxy.UpdateEndpointsMapResult{
187 DeletedUDPEndpoints: []proxy.ServiceEndpoint{},
188 NewlyActiveUDPServices: []proxy.ServicePortName{
189 udpPortName,
190 },
191 },
192
193 result: FakeInterface{
194 ClearedIPs: sets.New(testClusterIP, testExternalIP, testLoadBalancerIP),
195 ClearedPorts: sets.New(testNodePort),
196
197 ClearedNATs: map[string]string{},
198 ClearedPortNATs: map[int]string{},
199 },
200 },
201
202 {
203 description: "DeletedUDPEndpoints for unknown Service has no effect",
204
205 serviceUpdates: proxy.UpdateServiceMapResult{
206 DeletedUDPClusterIPs: sets.New[string](),
207 },
208 endpointsUpdates: proxy.UpdateEndpointsMapResult{
209 DeletedUDPEndpoints: []proxy.ServiceEndpoint{{
210 Endpoint: "10.240.0.4:80",
211 ServicePortName: unknownPortName,
212 }},
213 NewlyActiveUDPServices: []proxy.ServicePortName{},
214 },
215
216 result: FakeInterface{
217 ClearedIPs: sets.New[string](),
218 ClearedPorts: sets.New[int](),
219 ClearedNATs: map[string]string{},
220 ClearedPortNATs: map[int]string{},
221 },
222 },
223 {
224 description: "NewlyActiveUDPServices for unknown Service has no effect",
225
226 serviceUpdates: proxy.UpdateServiceMapResult{
227 DeletedUDPClusterIPs: sets.New[string](),
228 },
229 endpointsUpdates: proxy.UpdateEndpointsMapResult{
230 DeletedUDPEndpoints: []proxy.ServiceEndpoint{},
231 NewlyActiveUDPServices: []proxy.ServicePortName{
232 unknownPortName,
233 },
234 },
235
236 result: FakeInterface{
237 ClearedIPs: sets.New[string](),
238 ClearedPorts: sets.New[int](),
239 ClearedNATs: map[string]string{},
240 ClearedPortNATs: map[int]string{},
241 },
242 },
243 }
244
245 for _, tc := range testCases {
246 t.Run(tc.description, func(t *testing.T) {
247 fake := NewFake()
248 CleanStaleEntries(fake, svcPortMap, tc.serviceUpdates, tc.endpointsUpdates)
249 if !fake.ClearedIPs.Equal(tc.result.ClearedIPs) {
250 t.Errorf("Expected ClearedIPs=%v, got %v", tc.result.ClearedIPs, fake.ClearedIPs)
251 }
252 if !fake.ClearedPorts.Equal(tc.result.ClearedPorts) {
253 t.Errorf("Expected ClearedPorts=%v, got %v", tc.result.ClearedPorts, fake.ClearedPorts)
254 }
255 if !reflect.DeepEqual(fake.ClearedNATs, tc.result.ClearedNATs) {
256 t.Errorf("Expected ClearedNATs=%v, got %v", tc.result.ClearedNATs, fake.ClearedNATs)
257 }
258 if !reflect.DeepEqual(fake.ClearedPortNATs, tc.result.ClearedPortNATs) {
259 t.Errorf("Expected ClearedPortNATs=%v, got %v", tc.result.ClearedPortNATs, fake.ClearedPortNATs)
260 }
261 })
262 }
263 }
264
View as plain text