istio

Форк
0
/
ambientindex_workloadentry_test.go 
376 строк · 15.6 Кб
1
// Copyright Istio Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package ambient
16

17
import (
18
	"net/netip"
19
	"testing"
20

21
	corev1 "k8s.io/api/core/v1"
22
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23

24
	"istio.io/istio/pilot/pkg/features"
25
	"istio.io/istio/pilot/pkg/model"
26
	"istio.io/istio/pkg/config/constants"
27
	"istio.io/istio/pkg/config/schema/gvk"
28
	"istio.io/istio/pkg/test"
29
	"istio.io/istio/pkg/test/util/assert"
30
	"istio.io/istio/pkg/workloadapi"
31
)
32

33
func TestAmbientIndex_WorkloadEntries(t *testing.T) {
34
	s := newAmbientTestServer(t, testC, testNW)
35

36
	s.addWorkloadEntries(t, "127.0.0.1", "name1", "sa1", map[string]string{"app": "a"})
37
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1")
38
	s.assertEvent(t, s.wleXdsName("name1"))
39

40
	s.addWorkloadEntries(t, "127.0.0.2", "name2", "sa2", map[string]string{"app": "a", "other": "label"})
41
	s.addWorkloadEntries(t, "127.0.0.3", "name3", "sa3", map[string]string{"app": "other"})
42
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3")
43
	s.assertWorkloads(t, s.addrXdsName("127.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "name1")
44
	s.assertWorkloads(t, s.addrXdsName("127.0.0.2"), workloadapi.WorkloadStatus_HEALTHY, "name2")
45
	assert.Equal(t, s.lookup(s.addrXdsName("127.0.0.3")), []model.AddressInfo{{
46
		Address: &workloadapi.Address{
47
			Type: &workloadapi.Address_Workload{
48
				Workload: &workloadapi.Workload{
49
					Uid:               s.wleXdsName("name3"),
50
					Name:              "name3",
51
					Namespace:         testNS,
52
					Network:           testNW,
53
					Addresses:         [][]byte{parseIP("127.0.0.3")},
54
					ServiceAccount:    "sa3",
55
					Node:              "",
56
					CanonicalName:     "other",
57
					CanonicalRevision: "latest",
58
					WorkloadType:      workloadapi.WorkloadType_POD,
59
					WorkloadName:      "name3",
60
					ClusterId:         testC,
61
				},
62
			},
63
		},
64
	}})
65
	s.assertEvent(t, s.wleXdsName("name2"))
66
	s.assertEvent(t, s.wleXdsName("name3"))
67

68
	// Non-existent IP should have no response
69
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY)
70
	s.clearEvents()
71

72
	s.addService(t, "svc1", map[string]string{}, // labels
73
		map[string]string{}, // annotations
74
		[]int32{80},
75
		map[string]string{"app": "a"}, // selector
76
		"10.0.0.1",
77
	)
78
	// Service shouldn't change workload list
79
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3")
80
	s.assertWorkloads(t, s.addrXdsName("127.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "name1")
81
	// Now we should be able to look up a VIP as well
82
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "name1", "name2")
83
	// We should get an event for the two WEs and the selecting service impacted
84
	s.assertEvent(t, s.wleXdsName("name1"), s.wleXdsName("name2"), s.svcXdsName("svc1"))
85

86
	// Add a new pod to the service, we should see it
87
	s.addWorkloadEntries(t, "127.0.0.4", "name4", "sa4", map[string]string{"app": "a"})
88
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3", "name4")
89
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name4")
90
	s.assertEvent(t, s.wleXdsName("name4"))
91

92
	// Delete it, should remove from the Service as well
93
	s.deleteWorkloadEntry(t, "name4")
94
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3")
95
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "name1", "name2")
96
	s.assertWorkloads(t, s.addrXdsName("127.0.0.4"), workloadapi.WorkloadStatus_HEALTHY) // Should not be accessible anymore
97
	s.assertEvent(t, s.wleXdsName("name4"))
98

99
	s.clearEvents()
100
	// Update Service to have a more restrictive label selector
101
	s.addService(t, "svc1", map[string]string{}, // labels
102
		map[string]string{}, // annotations
103
		[]int32{80},
104
		map[string]string{"app": "a", "other": "label"}, // selector
105
		"10.0.0.1",
106
	)
107
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3")
108
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "name2")
109
	s.assertEvent(t, s.wleXdsName("name1"))
110

111
	// Update an existing WE into the service
112
	s.addWorkloadEntries(t, "127.0.0.3", "name3", "sa3", map[string]string{"app": "a", "other": "label"})
113
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3")
114
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "name2", "name3")
115
	s.assertEvent(t, s.wleXdsName("name3"))
116

117
	// And remove it again from the service VIP mapping by changing its label to not match the service svc1.ns1 selector
118
	s.addWorkloadEntries(t, "127.0.0.3", "name3", "sa3", map[string]string{"app": "a"})
119
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3")
120
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "name2")
121
	s.assertEvent(t, s.wleXdsName("name3"))
122

123
	// Delete the service entirely
124
	s.sc.Delete("svc1", "ns1")
125
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3")
126
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY)
127
	s.assertEvent(t, s.wleXdsName("name2"), s.svcXdsName("svc1"))
128

129
	// Add a waypoint proxy pod for namespace
130
	s.addPods(t, "127.0.0.200", "waypoint-ns-pod", "namespace-wide",
131
		map[string]string{
132
			constants.ManagedGatewayLabel: constants.ManagedGatewayMeshControllerLabel,
133
			constants.GatewayNameLabel:    "namespace-wide",
134
		}, nil, true, corev1.PodRunning)
135
	s.assertAddresses(t, "", "name1", "name2", "name3", "waypoint-ns-pod")
136
	s.assertEvent(t, s.podXdsName("waypoint-ns-pod"))
137
	s.addWaypoint(t, "10.0.0.2", "waypoint-ns", "", true)
138
	s.ns.CreateOrUpdate(&corev1.Namespace{
139
		ObjectMeta: metav1.ObjectMeta{
140
			Name: testNS,
141
			Annotations: map[string]string{
142
				constants.AmbientUseWaypoint: "waypoint-ns",
143
			},
144
		},
145
	})
146
	// All these workloads updated, so push them
147
	s.assertEvent(t,
148
		s.wleXdsName("name1"),
149
		s.wleXdsName("name2"),
150
		s.wleXdsName("name3"),
151
	)
152
	// create the waypoint service
153
	s.addService(t, "waypoint-ns",
154
		map[string]string{constants.ManagedGatewayLabel: constants.ManagedGatewayMeshControllerLabel}, // labels
155
		map[string]string{}, // annotations
156
		[]int32{80},
157
		map[string]string{constants.GatewayNameLabel: "namespace-wide"}, // selector
158
		"10.0.0.2",
159
	)
160
	s.assertEvent(t, s.podXdsName("waypoint-ns-pod"),
161
		s.svcXdsName("waypoint-ns"),
162
	)
163
	s.assertAddresses(t, "", "name1", "name2", "name3", "waypoint-ns", "waypoint-ns-pod")
164
	// We should now see the waypoint service IP
165
	assert.Equal(t,
166
		s.lookup(s.addrXdsName("127.0.0.3"))[0].Address.GetWorkload().Waypoint.GetAddress().Address,
167
		netip.MustParseAddr("10.0.0.2").AsSlice())
168

169
	// Add another one, expect the same result
170
	s.addPods(t, "127.0.0.201", "waypoint2-ns-pod", "namespace-wide",
171
		map[string]string{
172
			constants.ManagedGatewayLabel: constants.ManagedGatewayMeshControllerLabel,
173
			constants.GatewayNameLabel:    "namespace-wide",
174
		}, nil, true, corev1.PodRunning)
175
	s.assertAddresses(t, "", "name1", "name2", "name3", "waypoint-ns", "waypoint-ns-pod", "waypoint2-ns-pod")
176
	// all these workloads already have a waypoint, only expect the new waypoint pod
177
	s.assertEvent(t, s.podXdsName("waypoint2-ns-pod"))
178

179
	// Waypoints do not have waypoints
180
	assert.Equal(t,
181
		s.lookup(s.addrXdsName("127.0.0.200"))[0].Address.GetWorkload().GetWaypoint(),
182
		nil)
183

184
	s.addService(t, "svc1",
185
		map[string]string{}, // labels
186
		map[string]string{}, // annotations
187
		[]int32{80},
188
		map[string]string{"app": "a"}, // selector
189
		"10.0.0.1",
190
	)
191
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3")
192
	// Send update for the workloads as well...
193
	s.assertEvent(t, s.wleXdsName("name1"),
194
		s.wleXdsName("name2"),
195
		s.wleXdsName("name3"),
196
		s.svcXdsName("svc1"))
197

198
	// Delete a waypoint pod
199
	s.deletePod(t, "waypoint2-ns-pod")
200
	s.assertEvent(t, s.podXdsName("waypoint2-ns-pod")) // only expect event on the single waypoint pod
201

202
	// Adding a new WorkloadEntry should also see the waypoint
203
	s.addWorkloadEntries(t, "127.0.0.6", "name6", "sa6", map[string]string{"app": "a"})
204
	s.assertEvent(t, s.wleXdsName("name6"))
205
	assert.Equal(t,
206
		s.lookup(s.addrXdsName("127.0.0.6"))[0].Address.GetWorkload().Waypoint.GetAddress().Address,
207
		netip.MustParseAddr("10.0.0.2").AsSlice())
208

209
	s.deleteWorkloadEntry(t, "name6")
210
	s.assertEvent(t, s.wleXdsName("name6"))
211

212
	s.deleteWaypoint(t, "waypoint-ns")
213
	s.ns.Update(&corev1.Namespace{
214
		ObjectMeta: metav1.ObjectMeta{
215
			Name: testNS,
216
			Annotations: map[string]string{
217
				constants.AmbientUseWaypoint: "#none",
218
			},
219
		},
220
	})
221
	// all affected addresses with the waypoint should be updated
222
	s.assertEvent(t,
223
		s.svcXdsName("svc1"),
224
		s.svcXdsName("waypoint-ns"),
225
		s.wleXdsName("name1"),
226
		s.wleXdsName("name2"),
227
		s.wleXdsName("name3"))
228

229
	s.deleteService(t, "waypoint-ns")
230
	s.assertEvent(t, s.podXdsName("waypoint-ns-pod"),
231
		s.svcXdsName("waypoint-ns"))
232

233
	s.deleteWorkloadEntry(t, "name3")
234
	s.assertEvent(t, s.wleXdsName("name3"))
235
	s.deleteWorkloadEntry(t, "name2")
236
	s.assertEvent(t, s.wleXdsName("name2"))
237

238
	s.addPolicy(t, "global", "istio-system", nil, gvk.AuthorizationPolicy, nil)
239
	s.addPolicy(t, "namespace", "default", nil, gvk.AuthorizationPolicy, nil)
240
	assert.Equal(t,
241
		s.lookup(s.addrXdsName("127.0.0.1"))[0].GetWorkload().GetAuthorizationPolicies(),
242
		nil)
243
	s.clearEvents()
244

245
	s.addPolicy(t, "selector", "ns1", map[string]string{"app": "a"}, gvk.AuthorizationPolicy, nil)
246
	s.assertEvent(t, s.wleXdsName("name1"))
247
	assert.Equal(t,
248
		s.lookup(s.addrXdsName("127.0.0.1"))[0].GetWorkload().GetAuthorizationPolicies(),
249
		[]string{"ns1/selector"})
250

251
	// WorkloadEntry not in policy
252
	s.addWorkloadEntries(t, "127.0.0.2", "name2", "sa2", map[string]string{"app": "not-a"})
253
	s.assertEvent(t, s.wleXdsName("name2"))
254
	assert.Equal(t,
255
		s.lookup(s.addrXdsName("127.0.0.2"))[0].GetWorkload().GetAuthorizationPolicies(),
256
		nil)
257

258
	// Add it to the policy by updating its selector
259
	s.addWorkloadEntries(t, "127.0.0.2", "name2", "sa2", map[string]string{"app": "a"})
260
	s.assertEvent(t, s.wleXdsName("name2"))
261
	assert.Equal(t,
262
		s.lookup(s.addrXdsName("127.0.0.2"))[0].GetWorkload().GetAuthorizationPolicies(),
263
		[]string{"ns1/selector"})
264

265
	s.addPolicy(t, "global-selector", "istio-system", map[string]string{"app": "a"}, gvk.AuthorizationPolicy, nil)
266
	s.assertEvent(t, s.wleXdsName("name1"), s.wleXdsName("name2"))
267
	assert.Equal(t,
268
		s.lookup(s.addrXdsName("127.0.0.1"))[0].GetWorkload().GetAuthorizationPolicies(),
269
		[]string{"istio-system/global-selector", "ns1/selector"})
270

271
	// Update selector to not select
272
	s.addPolicy(t, "global-selector", "istio-system", map[string]string{"app": "not-a"}, gvk.AuthorizationPolicy, nil)
273
	s.assertEvent(t, s.wleXdsName("name1"), s.wleXdsName("name2"))
274
	assert.Equal(t,
275
		s.lookup(s.addrXdsName("127.0.0.1"))[0].GetWorkload().GetAuthorizationPolicies(),
276
		[]string{"ns1/selector"})
277

278
	s.authz.Delete("selector", "ns1")
279
	s.assertEvent(t, s.wleXdsName("name1"), s.wleXdsName("name2"))
280
	assert.Equal(t,
281
		s.lookup(s.addrXdsName("127.0.0.1"))[0].GetWorkload().GetAuthorizationPolicies(),
282
		nil)
283
}
284

285
func TestAmbientIndex_EmptyAddrWorkloadEntries(t *testing.T) {
286
	s := newAmbientTestServer(t, testC, testNW)
287
	s.addWorkloadEntries(t, "", "emptyaddr1", "sa1", map[string]string{"app": "a"})
288
	s.assertEvent(t, s.wleXdsName("emptyaddr1"))
289
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "emptyaddr1")
290

291
	s.addWorkloadEntries(t, "", "emptyaddr2", "sa1", map[string]string{"app": "a"})
292
	s.assertEvent(t, s.wleXdsName("emptyaddr2"))
293
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "emptyaddr1", "emptyaddr2")
294

295
	// ensure we stored and can fetch both; neither was blown away
296
	assert.Equal(t,
297
		s.lookup(s.wleXdsName("emptyaddr1"))[0].GetWorkload().GetName(),
298
		"emptyaddr1") // can lookup this workload by name
299
	assert.Equal(t,
300
		s.lookup(s.wleXdsName("emptyaddr2"))[0].GetWorkload().GetName(),
301
		"emptyaddr2") // can lookup this workload by name
302

303
	assert.Equal(t,
304
		len(s.lookup(s.addrXdsName(""))),
305
		0) // cannot lookup these workloads by address
306
}
307

308
func TestAmbientIndex_UpdateExistingWorkloadEntry(t *testing.T) {
309
	s := newAmbientTestServer(t, testC, testNW)
310
	s.addWorkloadEntries(t, "", "emptyaddr1", "sa1", map[string]string{"app": "a"})
311
	s.assertEvent(t, s.wleXdsName("emptyaddr1"))
312
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "emptyaddr1")
313

314
	// update service account for existing WE and expect a new xds event
315
	s.addWorkloadEntries(t, "", "emptyaddr1", "sa2", map[string]string{"app": "a"})
316
	s.assertEvent(t, s.wleXdsName("emptyaddr1"))
317
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "emptyaddr1")
318
}
319

320
func TestAmbientIndex_InlinedWorkloadEntries(t *testing.T) {
321
	s := newAmbientTestServer(t, testC, testNW)
322

323
	s.addServiceEntry(t, "se.istio.io", []string{"240.240.23.45"}, "se1", testNS, map[string]string{"app": "a"}, []string{"127.0.0.1", "127.0.0.2"})
324
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "se1")
325
	s.assertEvent(t, s.seIPXdsName("se1", "127.0.0.1"), s.seIPXdsName("se1", "127.0.0.2"), "ns1/se.istio.io")
326

327
	s.addPolicy(t, "selector", "ns1", map[string]string{"app": "a"}, gvk.AuthorizationPolicy, nil)
328
	s.assertEvent(t, s.seIPXdsName("se1", "127.0.0.1"), s.seIPXdsName("se1", "127.0.0.2"))
329
	assert.Equal(t,
330
		s.lookup(s.seIPXdsName("se1", "127.0.0.1"))[0].GetWorkload().GetAuthorizationPolicies(),
331
		[]string{"ns1/selector"})
332
	assert.Equal(t,
333
		s.lookup(s.seIPXdsName("se1", "127.0.0.2"))[0].GetWorkload().GetAuthorizationPolicies(),
334
		[]string{"ns1/selector"})
335

336
	s.deletePolicy("selector", "ns1", gvk.AuthorizationPolicy)
337
	s.assertEvent(t, s.seIPXdsName("se1", "127.0.0.1"), s.seIPXdsName("se1", "127.0.0.2"))
338
	assert.Equal(t,
339
		s.lookup(s.seIPXdsName("se1", "127.0.0.1"))[0].GetWorkload().GetAuthorizationPolicies(),
340
		nil)
341
	assert.Equal(t,
342
		s.lookup(s.seIPXdsName("se1", "127.0.0.2"))[0].GetWorkload().GetAuthorizationPolicies(),
343
		nil)
344

345
	s.deleteServiceEntry(t, "se1", testNS)
346
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY) // Asserting no WE residual
347
}
348

349
func TestAmbientIndex_WorkloadEntries_DisableK8SServiceSelectWorkloadEntries(t *testing.T) {
350
	test.SetForTest(t, &features.EnableK8SServiceSelectWorkloadEntries, false)
351
	s := newAmbientTestServer(t, testC, testNW)
352

353
	s.addWorkloadEntries(t, "127.0.0.1", "name1", "sa1", map[string]string{"app": "a"})
354
	s.assertEvent(t, s.wleXdsName("name1"))
355
	s.addWorkloadEntries(t, "127.0.0.2", "name2", "sa2", map[string]string{"app": "a", "other": "label"})
356
	s.assertEvent(t, s.wleXdsName("name2"))
357
	s.addWorkloadEntries(t, "127.0.0.3", "name3", "sa3", map[string]string{"app": "other"})
358
	s.assertEvent(t, s.wleXdsName("name3"))
359
	s.addPods(t, "127.0.0.201", "pod1", "pod1", map[string]string{"app": "a"}, nil, true, corev1.PodRunning)
360
	s.assertEvent(t, s.podXdsName("pod1"))
361

362
	s.addService(t, "svc1", map[string]string{}, // labels
363
		map[string]string{}, // annotations
364
		[]int32{80},
365
		map[string]string{"app": "a"}, // selector
366
		"10.0.0.1",
367
	)
368
	s.assertEvent(t, s.podXdsName("pod1"), "ns1/svc1.ns1.svc.company.com")
369

370
	s.clearEvents()
371
	s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1", "name2", "name3", "pod1")
372

373
	// Setting the PILOT_ENABLE_K8S_SELECT_WORKLOAD_ENTRIES to false shouldn't include workload entries when
374
	// looking up by the k8s service address
375
	s.assertWorkloads(t, s.addrXdsName("10.0.0.1"), workloadapi.WorkloadStatus_HEALTHY, "pod1")
376
}
377

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.