istio

Форк
0
1300 строк · 38.8 Кб
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 serviceentry
16

17
import (
18
	"encoding/json"
19
	"strings"
20
	"testing"
21
	"time"
22

23
	"istio.io/api/label"
24
	networking "istio.io/api/networking/v1alpha3"
25
	"istio.io/istio/pilot/pkg/features"
26
	"istio.io/istio/pilot/pkg/model"
27
	"istio.io/istio/pilot/pkg/serviceregistry/provider"
28
	labelutil "istio.io/istio/pilot/pkg/serviceregistry/util/label"
29
	"istio.io/istio/pilot/test/util"
30
	"istio.io/istio/pkg/cluster"
31
	"istio.io/istio/pkg/config"
32
	"istio.io/istio/pkg/config/constants"
33
	"istio.io/istio/pkg/config/host"
34
	"istio.io/istio/pkg/config/labels"
35
	"istio.io/istio/pkg/config/protocol"
36
	"istio.io/istio/pkg/config/schema/gvk"
37
	"istio.io/istio/pkg/network"
38
	"istio.io/istio/pkg/spiffe"
39
	"istio.io/istio/pkg/test"
40
)
41

42
var (
43
	GlobalTime = time.Now()
44
	httpNone   = &config.Config{
45
		Meta: config.Meta{
46
			GroupVersionKind:  gvk.ServiceEntry,
47
			Name:              "httpNone",
48
			Namespace:         "httpNone",
49
			Domain:            "svc.cluster.local",
50
			CreationTimestamp: GlobalTime,
51
		},
52
		Spec: &networking.ServiceEntry{
53
			Hosts: []string{"*.google.com"},
54
			Ports: []*networking.ServicePort{
55
				{Number: 80, Name: "http-number", Protocol: "http"},
56
				{Number: 8080, Name: "http2-number", Protocol: "http2"},
57
			},
58
			Location:   networking.ServiceEntry_MESH_EXTERNAL,
59
			Resolution: networking.ServiceEntry_NONE,
60
		},
61
	}
62
)
63

64
var tcpNone = &config.Config{
65
	Meta: config.Meta{
66
		GroupVersionKind:  gvk.ServiceEntry,
67
		Name:              "tcpNone",
68
		Namespace:         "tcpNone",
69
		CreationTimestamp: GlobalTime,
70
	},
71
	Spec: &networking.ServiceEntry{
72
		Hosts:     []string{"tcpnone.com"},
73
		Addresses: []string{"172.217.0.0/16"},
74
		Ports: []*networking.ServicePort{
75
			{Number: 444, Name: "tcp-444", Protocol: "tcp"},
76
		},
77
		Location:   networking.ServiceEntry_MESH_EXTERNAL,
78
		Resolution: networking.ServiceEntry_NONE,
79
	},
80
}
81

82
var httpStatic = &config.Config{
83
	Meta: config.Meta{
84
		GroupVersionKind:  gvk.ServiceEntry,
85
		Name:              "httpStatic",
86
		Namespace:         "httpStatic",
87
		CreationTimestamp: GlobalTime,
88
	},
89
	Spec: &networking.ServiceEntry{
90
		Hosts: []string{"*.google.com"},
91
		Ports: []*networking.ServicePort{
92
			{Number: 80, Name: "http-port", Protocol: "http"},
93
			{Number: 8080, Name: "http-alt-port", Protocol: "http"},
94
		},
95
		Endpoints: []*networking.WorkloadEntry{
96
			{
97
				Address: "2.2.2.2",
98
				Ports:   map[string]uint32{"http-port": 7080, "http-alt-port": 18080},
99
				Labels:  map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
100
			},
101
			{
102
				Address: "3.3.3.3",
103
				Ports:   map[string]uint32{"http-port": 1080},
104
				Labels:  map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
105
			},
106
			{
107
				Address: "4.4.4.4",
108
				Ports:   map[string]uint32{"http-port": 1080},
109
				Labels:  map[string]string{"foo": "bar"},
110
			},
111
		},
112
		Location:   networking.ServiceEntry_MESH_EXTERNAL,
113
		Resolution: networking.ServiceEntry_STATIC,
114
	},
115
}
116

117
// Shares the same host as httpStatic, but adds some endpoints. We expect these to be merge
118
var httpStaticOverlay = &config.Config{
119
	Meta: config.Meta{
120
		GroupVersionKind:  gvk.ServiceEntry,
121
		Name:              "httpStaticOverlay",
122
		Namespace:         "httpStatic",
123
		CreationTimestamp: GlobalTime,
124
	},
125
	Spec: &networking.ServiceEntry{
126
		Hosts: []string{"*.google.com"},
127
		Ports: []*networking.ServicePort{
128
			{Number: 4567, Name: "http-port", Protocol: "http"},
129
		},
130
		Endpoints: []*networking.WorkloadEntry{
131
			{
132
				Address: "5.5.5.5",
133
				Labels:  map[string]string{"overlay": "bar"},
134
			},
135
		},
136
		Location:   networking.ServiceEntry_MESH_EXTERNAL,
137
		Resolution: networking.ServiceEntry_STATIC,
138
	},
139
}
140

141
var httpDNSnoEndpoints = &config.Config{
142
	Meta: config.Meta{
143
		GroupVersionKind:  gvk.ServiceEntry,
144
		Name:              "httpDNSnoEndpoints",
145
		Namespace:         "httpDNSnoEndpoints",
146
		CreationTimestamp: GlobalTime,
147
	},
148
	Spec: &networking.ServiceEntry{
149
		Hosts: []string{"google.com", "www.wikipedia.org"},
150
		Ports: []*networking.ServicePort{
151
			{Number: 80, Name: "http-port", Protocol: "http"},
152
			{Number: 8080, Name: "http-alt-port", Protocol: "http"},
153
		},
154
		Location:        networking.ServiceEntry_MESH_EXTERNAL,
155
		Resolution:      networking.ServiceEntry_DNS,
156
		SubjectAltNames: []string{"google.com"},
157
	},
158
}
159

160
var httpDNSRRnoEndpoints = &config.Config{
161
	Meta: config.Meta{
162
		GroupVersionKind:  gvk.ServiceEntry,
163
		Name:              "httpDNSRRnoEndpoints",
164
		Namespace:         "httpDNSRRnoEndpoints",
165
		CreationTimestamp: GlobalTime,
166
	},
167
	Spec: &networking.ServiceEntry{
168
		Hosts: []string{"api.istio.io"},
169
		Ports: []*networking.ServicePort{
170
			{Number: 80, Name: "http-port", Protocol: "http"},
171
			{Number: 8080, Name: "http-alt-port", Protocol: "http"},
172
		},
173
		Location:        networking.ServiceEntry_MESH_EXTERNAL,
174
		Resolution:      networking.ServiceEntry_DNS_ROUND_ROBIN,
175
		SubjectAltNames: []string{"api.istio.io"},
176
	},
177
}
178

179
var dnsTargetPort = &config.Config{
180
	Meta: config.Meta{
181
		GroupVersionKind:  gvk.ServiceEntry,
182
		Name:              "dnsTargetPort",
183
		Namespace:         "dnsTargetPort",
184
		CreationTimestamp: GlobalTime,
185
	},
186
	Spec: &networking.ServiceEntry{
187
		Hosts: []string{"google.com"},
188
		Ports: []*networking.ServicePort{
189
			{Number: 80, Name: "http-port", Protocol: "http", TargetPort: 8080},
190
		},
191
		Location:   networking.ServiceEntry_MESH_EXTERNAL,
192
		Resolution: networking.ServiceEntry_DNS,
193
	},
194
}
195

196
var httpDNS = &config.Config{
197
	Meta: config.Meta{
198
		GroupVersionKind:  gvk.ServiceEntry,
199
		Name:              "httpDNS",
200
		Namespace:         "httpDNS",
201
		CreationTimestamp: GlobalTime,
202
	},
203
	Spec: &networking.ServiceEntry{
204
		Hosts: []string{"*.google.com"},
205
		Ports: []*networking.ServicePort{
206
			{Number: 80, Name: "http-port", Protocol: "http"},
207
			{Number: 8080, Name: "http-alt-port", Protocol: "http"},
208
		},
209
		Endpoints: []*networking.WorkloadEntry{
210
			{
211
				Address: "us.google.com",
212
				Ports:   map[string]uint32{"http-port": 7080, "http-alt-port": 18080},
213
				Labels:  map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
214
			},
215
			{
216
				Address: "uk.google.com",
217
				Ports:   map[string]uint32{"http-port": 1080},
218
				Labels:  map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
219
			},
220
			{
221
				Address: "de.google.com",
222
				Labels:  map[string]string{"foo": "bar", label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
223
			},
224
		},
225
		Location:   networking.ServiceEntry_MESH_EXTERNAL,
226
		Resolution: networking.ServiceEntry_DNS,
227
	},
228
}
229

230
var httpDNSRR = &config.Config{
231
	Meta: config.Meta{
232
		GroupVersionKind:  gvk.ServiceEntry,
233
		Name:              "httpDNSRR",
234
		Namespace:         "httpDNSRR",
235
		CreationTimestamp: GlobalTime,
236
	},
237
	Spec: &networking.ServiceEntry{
238
		Hosts: []string{"*.istio.io"},
239
		Ports: []*networking.ServicePort{
240
			{Number: 80, Name: "http-port", Protocol: "http"},
241
			{Number: 8080, Name: "http-alt-port", Protocol: "http"},
242
		},
243
		Endpoints: []*networking.WorkloadEntry{
244
			{
245
				Address: "api-v1.istio.io",
246
				Ports:   map[string]uint32{"http-port": 7080, "http-alt-port": 18080},
247
				Labels:  map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
248
			},
249
		},
250
		Location:   networking.ServiceEntry_MESH_EXTERNAL,
251
		Resolution: networking.ServiceEntry_DNS_ROUND_ROBIN,
252
	},
253
}
254

255
var tcpDNS = &config.Config{
256
	Meta: config.Meta{
257
		GroupVersionKind:  gvk.ServiceEntry,
258
		Name:              "tcpDNS",
259
		Namespace:         "tcpDNS",
260
		CreationTimestamp: GlobalTime,
261
	},
262
	Spec: &networking.ServiceEntry{
263
		Hosts: []string{"tcpdns.com"},
264
		Ports: []*networking.ServicePort{
265
			{Number: 444, Name: "tcp-444", Protocol: "tcp"},
266
		},
267
		Endpoints: []*networking.WorkloadEntry{
268
			{
269
				Address: "lon.google.com",
270
				Labels:  map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
271
			},
272
			{
273
				Address: "in.google.com",
274
				Labels:  map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
275
			},
276
		},
277
		Location:   networking.ServiceEntry_MESH_EXTERNAL,
278
		Resolution: networking.ServiceEntry_DNS,
279
	},
280
}
281

282
var tcpStatic = &config.Config{
283
	Meta: config.Meta{
284
		GroupVersionKind:  gvk.ServiceEntry,
285
		Name:              "tcpStatic",
286
		Namespace:         "tcpStatic",
287
		CreationTimestamp: GlobalTime,
288
	},
289
	Spec: &networking.ServiceEntry{
290
		Hosts:     []string{"tcpstatic.com"},
291
		Addresses: []string{"172.217.0.1"},
292
		Ports: []*networking.ServicePort{
293
			{Number: 444, Name: "tcp-444", Protocol: "tcp"},
294
		},
295
		Endpoints: []*networking.WorkloadEntry{
296
			{
297
				Address: "1.1.1.1",
298
				Labels:  map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
299
			},
300
			{
301
				Address: "2.2.2.2",
302
				Labels:  map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
303
			},
304
		},
305
		Location:   networking.ServiceEntry_MESH_EXTERNAL,
306
		Resolution: networking.ServiceEntry_STATIC,
307
	},
308
}
309

310
var httpNoneInternal = &config.Config{
311
	Meta: config.Meta{
312
		GroupVersionKind:  gvk.ServiceEntry,
313
		Name:              "httpNoneInternal",
314
		Namespace:         "httpNoneInternal",
315
		CreationTimestamp: GlobalTime,
316
	},
317
	Spec: &networking.ServiceEntry{
318
		Hosts: []string{"*.google.com"},
319
		Ports: []*networking.ServicePort{
320
			{Number: 80, Name: "http-number", Protocol: "http"},
321
			{Number: 8080, Name: "http2-number", Protocol: "http2"},
322
		},
323
		Location:   networking.ServiceEntry_MESH_INTERNAL,
324
		Resolution: networking.ServiceEntry_NONE,
325
	},
326
}
327

328
var tcpNoneInternal = &config.Config{
329
	Meta: config.Meta{
330
		GroupVersionKind:  gvk.ServiceEntry,
331
		Name:              "tcpNoneInternal",
332
		Namespace:         "tcpNoneInternal",
333
		CreationTimestamp: GlobalTime,
334
	},
335
	Spec: &networking.ServiceEntry{
336
		Hosts:     []string{"tcpinternal.com"},
337
		Addresses: []string{"172.217.0.0/16"},
338
		Ports: []*networking.ServicePort{
339
			{Number: 444, Name: "tcp-444", Protocol: "tcp"},
340
		},
341
		Location:   networking.ServiceEntry_MESH_INTERNAL,
342
		Resolution: networking.ServiceEntry_NONE,
343
	},
344
}
345

346
var multiAddrInternal = &config.Config{
347
	Meta: config.Meta{
348
		GroupVersionKind:  gvk.ServiceEntry,
349
		Name:              "multiAddrInternal",
350
		Namespace:         "multiAddrInternal",
351
		CreationTimestamp: GlobalTime,
352
	},
353
	Spec: &networking.ServiceEntry{
354
		Hosts:     []string{"tcp1.com", "tcp2.com"},
355
		Addresses: []string{"1.1.1.0/16", "2.2.2.0/16"},
356
		Ports: []*networking.ServicePort{
357
			{Number: 444, Name: "tcp-444", Protocol: "tcp"},
358
		},
359
		Location:   networking.ServiceEntry_MESH_INTERNAL,
360
		Resolution: networking.ServiceEntry_NONE,
361
	},
362
}
363

364
var udsLocal = &config.Config{
365
	Meta: config.Meta{
366
		GroupVersionKind:  gvk.ServiceEntry,
367
		Name:              "udsLocal",
368
		Namespace:         "udsLocal",
369
		CreationTimestamp: GlobalTime,
370
		Labels:            map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
371
	},
372
	Spec: &networking.ServiceEntry{
373
		Hosts: []string{"uds.cluster.local"},
374
		Ports: []*networking.ServicePort{
375
			{Number: 6553, Name: "grpc-1", Protocol: "grpc"},
376
		},
377
		Endpoints: []*networking.WorkloadEntry{
378
			{Address: "unix:///test/sock", Labels: map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel}},
379
		},
380
		Resolution: networking.ServiceEntry_STATIC,
381
	},
382
}
383

384
// ServiceEntry DNS with a selector
385
var selectorDNS = &config.Config{
386
	Meta: config.Meta{
387
		GroupVersionKind:  gvk.ServiceEntry,
388
		Name:              "selector",
389
		Namespace:         "selector",
390
		CreationTimestamp: GlobalTime,
391
	},
392
	Spec: &networking.ServiceEntry{
393
		Hosts: []string{"selector.com"},
394
		Ports: []*networking.ServicePort{
395
			{Number: 444, Name: "tcp-444", Protocol: "tcp"},
396
			{Number: 445, Name: "http-445", Protocol: "http"},
397
		},
398
		WorkloadSelector: &networking.WorkloadSelector{
399
			Labels: map[string]string{"app": "wle"},
400
		},
401
		Resolution: networking.ServiceEntry_DNS,
402
	},
403
}
404

405
// ServiceEntry with a selector
406
var selector = &config.Config{
407
	Meta: config.Meta{
408
		GroupVersionKind:  gvk.ServiceEntry,
409
		Name:              "selector",
410
		Namespace:         "selector",
411
		CreationTimestamp: GlobalTime,
412
	},
413
	Spec: &networking.ServiceEntry{
414
		Hosts: []string{"selector.com"},
415
		Ports: []*networking.ServicePort{
416
			{Number: 444, Name: "tcp-444", Protocol: "tcp"},
417
			{Number: 445, Name: "http-445", Protocol: "http"},
418
		},
419
		WorkloadSelector: &networking.WorkloadSelector{
420
			Labels: map[string]string{"app": "wle"},
421
		},
422
		Resolution: networking.ServiceEntry_STATIC,
423
	},
424
}
425

426
// DNS ServiceEntry with a selector
427
var dnsSelector = &config.Config{
428
	Meta: config.Meta{
429
		GroupVersionKind:  gvk.ServiceEntry,
430
		Name:              "dns-selector",
431
		Namespace:         "dns-selector",
432
		CreationTimestamp: GlobalTime,
433
		Labels:            map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
434
	},
435
	Spec: &networking.ServiceEntry{
436
		Hosts: []string{"dns.selector.com"},
437
		Ports: []*networking.ServicePort{
438
			{Number: 444, Name: "tcp-444", Protocol: "tcp"},
439
			{Number: 445, Name: "http-445", Protocol: "http"},
440
		},
441
		WorkloadSelector: &networking.WorkloadSelector{
442
			Labels: map[string]string{"app": "dns-wle"},
443
		},
444
		Resolution: networking.ServiceEntry_DNS,
445
	},
446
}
447

448
// Service Entry with DNSRoundRobinLB
449
var dnsRoundRobinLBSE1 = &config.Config{
450
	Meta: config.Meta{
451
		GroupVersionKind:  gvk.ServiceEntry,
452
		Name:              "dns-round-robin-1",
453
		Namespace:         "dns",
454
		CreationTimestamp: GlobalTime,
455
		Labels:            map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
456
	},
457
	Spec: &networking.ServiceEntry{
458
		Hosts: []string{"example.com"},
459
		Ports: []*networking.ServicePort{
460
			{Number: 445, Name: "http-445", Protocol: "http"},
461
			{Number: 446, Name: "http-446", Protocol: "http"},
462
		},
463
		Resolution: networking.ServiceEntry_DNS_ROUND_ROBIN,
464
	},
465
}
466

467
var dnsRoundRobinLBSE2 = &config.Config{
468
	Meta: config.Meta{
469
		GroupVersionKind:  gvk.ServiceEntry,
470
		Name:              "dns-round-robin-2",
471
		Namespace:         "dns",
472
		CreationTimestamp: GlobalTime,
473
		Labels:            map[string]string{label.SecurityTlsMode.Name: model.IstioMutualTLSModeLabel},
474
	},
475
	Spec: &networking.ServiceEntry{
476
		Hosts: []string{"example.com"},
477
		Ports: []*networking.ServicePort{
478
			{Number: 445, Name: "http-445", Protocol: "http"},
479
		},
480
		Resolution: networking.ServiceEntry_DNS_ROUND_ROBIN,
481
	},
482
}
483

484
func createWorkloadEntry(name, namespace string, spec *networking.WorkloadEntry) *config.Config {
485
	return &config.Config{
486
		Meta: config.Meta{
487
			GroupVersionKind:  gvk.WorkloadEntry,
488
			Name:              name,
489
			Namespace:         namespace,
490
			CreationTimestamp: GlobalTime,
491
		},
492
		Spec: spec,
493
	}
494
}
495

496
func convertPortNameToProtocol(name string) protocol.Instance {
497
	prefix := name
498
	i := strings.Index(name, "-")
499
	if i >= 0 {
500
		prefix = name[:i]
501
	}
502
	return protocol.Parse(prefix)
503
}
504

505
func makeService(hostname host.Name, configNamespace, address string, ports map[string]int,
506
	external bool, resolution model.Resolution, serviceAccounts ...string,
507
) *model.Service {
508
	svc := &model.Service{
509
		CreationTime:    GlobalTime,
510
		Hostname:        hostname,
511
		DefaultAddress:  address,
512
		MeshExternal:    external,
513
		Resolution:      resolution,
514
		ServiceAccounts: serviceAccounts,
515
		Attributes: model.ServiceAttributes{
516
			ServiceRegistry: provider.External,
517
			Name:            string(hostname),
518
			Namespace:       configNamespace,
519
		},
520
	}
521

522
	if external && features.CanonicalServiceForMeshExternalServiceEntry {
523
		if svc.Attributes.Labels == nil {
524
			svc.Attributes.Labels = make(map[string]string)
525
		}
526
		svc.Attributes.Labels["service.istio.io/canonical-name"] = configNamespace
527
		svc.Attributes.Labels["service.istio.io/canonical-revision"] = "latest"
528
	}
529

530
	svcPorts := make(model.PortList, 0, len(ports))
531
	for name, port := range ports {
532
		svcPort := &model.Port{
533
			Name:     name,
534
			Port:     port,
535
			Protocol: convertPortNameToProtocol(name),
536
		}
537
		svcPorts = append(svcPorts, svcPort)
538
	}
539

540
	sortPorts(svcPorts)
541
	svc.Ports = svcPorts
542
	return svc
543
}
544

545
// MTLSMode is the expected instance mtls settings. This is for test setup only
546
type MTLSMode int
547

548
const (
549
	MTLS = iota
550
	// Like mTLS, but no label is defined on the endpoint
551
	MTLSUnlabelled
552
	PlainText
553
)
554

555
// nolint: unparam
556
func makeInstanceWithServiceAccount(cfg *config.Config, address string, port int,
557
	svcPort *networking.ServicePort, svcLabels map[string]string, serviceAccount string,
558
) *model.ServiceInstance {
559
	i := makeInstance(cfg, address, port, svcPort, svcLabels, MTLSUnlabelled)
560
	i.Endpoint.ServiceAccount = spiffe.MustGenSpiffeURI(i.Service.Attributes.Namespace, serviceAccount)
561
	return i
562
}
563

564
// nolint: unparam
565
func makeTarget(cfg *config.Config, address string, port int,
566
	svcPort *networking.ServicePort, svcLabels map[string]string, mtlsMode MTLSMode,
567
) model.ServiceTarget {
568
	services := convertServices(*cfg)
569
	svc := services[0] // default
570
	for _, s := range services {
571
		if string(s.Hostname) == address {
572
			svc = s
573
			break
574
		}
575
	}
576
	if mtlsMode == MTLS {
577
		if svcLabels == nil {
578
			svcLabels = map[string]string{}
579
		}
580
		svcLabels[label.SecurityTlsMode.Name] = model.IstioMutualTLSModeLabel
581
	}
582
	return model.ServiceTarget{
583
		Service: svc,
584
		Port: model.ServiceInstancePort{
585
			ServicePort: &model.Port{
586
				Name:     svcPort.Name,
587
				Port:     int(svcPort.Number),
588
				Protocol: protocol.Parse(svcPort.Protocol),
589
			},
590
			TargetPort: uint32(port),
591
		},
592
	}
593
}
594

595
// nolint: unparam
596
func makeInstance(cfg *config.Config, address string, port int,
597
	svcPort *networking.ServicePort, svcLabels map[string]string, mtlsMode MTLSMode,
598
) *model.ServiceInstance {
599
	services := convertServices(*cfg)
600
	svc := services[0] // default
601
	for _, s := range services {
602
		if string(s.Hostname) == address {
603
			svc = s
604
			break
605
		}
606
	}
607
	tlsMode := model.DisabledTLSModeLabel
608
	if mtlsMode == MTLS || mtlsMode == MTLSUnlabelled {
609
		tlsMode = model.IstioMutualTLSModeLabel
610
	}
611
	if mtlsMode == MTLS {
612
		if svcLabels == nil {
613
			svcLabels = map[string]string{}
614
		}
615
		svcLabels[label.SecurityTlsMode.Name] = model.IstioMutualTLSModeLabel
616
	}
617
	return &model.ServiceInstance{
618
		Service: svc,
619
		Endpoint: &model.IstioEndpoint{
620
			Address:         address,
621
			EndpointPort:    uint32(port),
622
			ServicePortName: svcPort.Name,
623
			Labels:          svcLabels,
624
			TLSMode:         tlsMode,
625
		},
626
		ServicePort: &model.Port{
627
			Name:     svcPort.Name,
628
			Port:     int(svcPort.Number),
629
			Protocol: protocol.Parse(svcPort.Protocol),
630
		},
631
	}
632
}
633

634
func TestConvertService(t *testing.T) {
635
	testConvertServiceBody(t)
636
	test.SetForTest(t, &features.CanonicalServiceForMeshExternalServiceEntry, true)
637
	testConvertServiceBody(t)
638
}
639

640
func testConvertServiceBody(t *testing.T) {
641
	t.Helper()
642

643
	serviceTests := []struct {
644
		externalSvc *config.Config
645
		services    []*model.Service
646
	}{
647
		{
648
			// service entry http
649
			externalSvc: httpNone,
650
			services: []*model.Service{
651
				makeService("*.google.com", "httpNone", constants.UnspecifiedIP,
652
					map[string]int{"http-number": 80, "http2-number": 8080}, true, model.Passthrough),
653
			},
654
		},
655
		{
656
			// service entry tcp
657
			externalSvc: tcpNone,
658
			services: []*model.Service{
659
				makeService("tcpnone.com", "tcpNone", "172.217.0.0/16",
660
					map[string]int{"tcp-444": 444}, true, model.Passthrough),
661
			},
662
		},
663
		{
664
			// service entry http  static
665
			externalSvc: httpStatic,
666
			services: []*model.Service{
667
				makeService("*.google.com", "httpStatic", constants.UnspecifiedIP,
668
					map[string]int{"http-port": 80, "http-alt-port": 8080}, true, model.ClientSideLB),
669
			},
670
		},
671
		{
672
			// service entry DNS with no endpoints
673
			externalSvc: httpDNSnoEndpoints,
674
			services: []*model.Service{
675
				makeService("google.com", "httpDNSnoEndpoints", constants.UnspecifiedIP,
676
					map[string]int{"http-port": 80, "http-alt-port": 8080}, true, model.DNSLB, "google.com"),
677
				makeService("www.wikipedia.org", "httpDNSnoEndpoints", constants.UnspecifiedIP,
678
					map[string]int{"http-port": 80, "http-alt-port": 8080}, true, model.DNSLB, "google.com"),
679
			},
680
		},
681
		{
682
			// service entry dns
683
			externalSvc: httpDNS,
684
			services: []*model.Service{
685
				makeService("*.google.com", "httpDNS", constants.UnspecifiedIP,
686
					map[string]int{"http-port": 80, "http-alt-port": 8080}, true, model.DNSLB),
687
			},
688
		},
689
		{
690
			// service entry dns with target port
691
			externalSvc: dnsTargetPort,
692
			services: []*model.Service{
693
				makeService("google.com", "dnsTargetPort", constants.UnspecifiedIP,
694
					map[string]int{"http-port": 80}, true, model.DNSLB),
695
			},
696
		},
697
		{
698
			// service entry tcp DNS
699
			externalSvc: tcpDNS,
700
			services: []*model.Service{
701
				makeService("tcpdns.com", "tcpDNS", constants.UnspecifiedIP,
702
					map[string]int{"tcp-444": 444}, true, model.DNSLB),
703
			},
704
		},
705
		{
706
			// service entry tcp static
707
			externalSvc: tcpStatic,
708
			services: []*model.Service{
709
				makeService("tcpstatic.com", "tcpStatic", "172.217.0.1",
710
					map[string]int{"tcp-444": 444}, true, model.ClientSideLB),
711
			},
712
		},
713
		{
714
			// service entry http internal
715
			externalSvc: httpNoneInternal,
716
			services: []*model.Service{
717
				makeService("*.google.com", "httpNoneInternal", constants.UnspecifiedIP,
718
					map[string]int{"http-number": 80, "http2-number": 8080}, false, model.Passthrough),
719
			},
720
		},
721
		{
722
			// service entry tcp internal
723
			externalSvc: tcpNoneInternal,
724
			services: []*model.Service{
725
				makeService("tcpinternal.com", "tcpNoneInternal", "172.217.0.0/16",
726
					map[string]int{"tcp-444": 444}, false, model.Passthrough),
727
			},
728
		},
729
		{
730
			// service entry multiAddrInternal
731
			externalSvc: multiAddrInternal,
732
			services: []*model.Service{
733
				makeService("tcp1.com", "multiAddrInternal", "1.1.1.0/16",
734
					map[string]int{"tcp-444": 444}, false, model.Passthrough),
735
				makeService("tcp1.com", "multiAddrInternal", "2.2.2.0/16",
736
					map[string]int{"tcp-444": 444}, false, model.Passthrough),
737
				makeService("tcp2.com", "multiAddrInternal", "1.1.1.0/16",
738
					map[string]int{"tcp-444": 444}, false, model.Passthrough),
739
				makeService("tcp2.com", "multiAddrInternal", "2.2.2.0/16",
740
					map[string]int{"tcp-444": 444}, false, model.Passthrough),
741
			},
742
		},
743
	}
744

745
	selectorSvc := makeService("selector.com", "selector", "0.0.0.0",
746
		map[string]int{"tcp-444": 444, "http-445": 445}, true, model.ClientSideLB)
747
	selectorSvc.Attributes.LabelSelectors = map[string]string{"app": "wle"}
748

749
	serviceTests = append(serviceTests, struct {
750
		externalSvc *config.Config
751
		services    []*model.Service
752
	}{
753
		externalSvc: selector,
754
		services:    []*model.Service{selectorSvc},
755
	})
756

757
	for _, tt := range serviceTests {
758
		services := convertServices(*tt.externalSvc)
759
		if err := compare(t, services, tt.services); err != nil {
760
			t.Errorf("testcase: %v\n%v ", tt.externalSvc.Name, err)
761
		}
762
	}
763
}
764

765
func TestConvertInstances(t *testing.T) {
766
	serviceInstanceTests := []struct {
767
		externalSvc *config.Config
768
		out         []*model.ServiceInstance
769
	}{
770
		{
771
			// single instance with multiple ports
772
			externalSvc: httpNone,
773
			// DNS type none means service should not have a registered instance
774
			out: []*model.ServiceInstance{},
775
		},
776
		{
777
			// service entry tcp
778
			externalSvc: tcpNone,
779
			// DNS type none means service should not have a registered instance
780
			out: []*model.ServiceInstance{},
781
		},
782
		{
783
			// service entry static
784
			externalSvc: httpStatic,
785
			out: []*model.ServiceInstance{
786
				makeInstance(httpStatic, "2.2.2.2", 7080, httpStatic.Spec.(*networking.ServiceEntry).Ports[0], nil, MTLS),
787
				makeInstance(httpStatic, "2.2.2.2", 18080, httpStatic.Spec.(*networking.ServiceEntry).Ports[1], nil, MTLS),
788
				makeInstance(httpStatic, "3.3.3.3", 1080, httpStatic.Spec.(*networking.ServiceEntry).Ports[0], nil, MTLS),
789
				makeInstance(httpStatic, "3.3.3.3", 8080, httpStatic.Spec.(*networking.ServiceEntry).Ports[1], nil, MTLS),
790
				makeInstance(httpStatic, "4.4.4.4", 1080, httpStatic.Spec.(*networking.ServiceEntry).Ports[0], map[string]string{"foo": "bar"}, PlainText),
791
				makeInstance(httpStatic, "4.4.4.4", 8080, httpStatic.Spec.(*networking.ServiceEntry).Ports[1], map[string]string{"foo": "bar"}, PlainText),
792
			},
793
		},
794
		{
795
			// service entry DNS with no endpoints
796
			externalSvc: httpDNSnoEndpoints,
797
			out: []*model.ServiceInstance{
798
				makeInstance(httpDNSnoEndpoints, "google.com", 80, httpDNSnoEndpoints.Spec.(*networking.ServiceEntry).Ports[0], nil, PlainText),
799
				makeInstance(httpDNSnoEndpoints, "google.com", 8080, httpDNSnoEndpoints.Spec.(*networking.ServiceEntry).Ports[1], nil, PlainText),
800
				makeInstance(httpDNSnoEndpoints, "www.wikipedia.org", 80, httpDNSnoEndpoints.Spec.(*networking.ServiceEntry).Ports[0], nil, PlainText),
801
				makeInstance(httpDNSnoEndpoints, "www.wikipedia.org", 8080, httpDNSnoEndpoints.Spec.(*networking.ServiceEntry).Ports[1], nil, PlainText),
802
			},
803
		},
804
		{
805
			// service entry DNS with no endpoints using round robin
806
			externalSvc: httpDNSRRnoEndpoints,
807
			out: []*model.ServiceInstance{
808
				makeInstance(httpDNSRRnoEndpoints, "api.istio.io", 80, httpDNSnoEndpoints.Spec.(*networking.ServiceEntry).Ports[0], nil, PlainText),
809
				makeInstance(httpDNSRRnoEndpoints, "api.istio.io", 8080, httpDNSnoEndpoints.Spec.(*networking.ServiceEntry).Ports[1], nil, PlainText),
810
			},
811
		},
812
		{
813
			// service entry DNS with workload selector and no endpoints
814
			externalSvc: selectorDNS,
815
			out:         []*model.ServiceInstance{},
816
		},
817
		{
818
			// service entry dns
819
			externalSvc: httpDNS,
820
			out: []*model.ServiceInstance{
821
				makeInstance(httpDNS, "us.google.com", 7080, httpDNS.Spec.(*networking.ServiceEntry).Ports[0], nil, MTLS),
822
				makeInstance(httpDNS, "us.google.com", 18080, httpDNS.Spec.(*networking.ServiceEntry).Ports[1], nil, MTLS),
823
				makeInstance(httpDNS, "uk.google.com", 1080, httpDNS.Spec.(*networking.ServiceEntry).Ports[0], nil, MTLS),
824
				makeInstance(httpDNS, "uk.google.com", 8080, httpDNS.Spec.(*networking.ServiceEntry).Ports[1], nil, MTLS),
825
				makeInstance(httpDNS, "de.google.com", 80, httpDNS.Spec.(*networking.ServiceEntry).Ports[0], map[string]string{"foo": "bar"}, MTLS),
826
				makeInstance(httpDNS, "de.google.com", 8080, httpDNS.Spec.(*networking.ServiceEntry).Ports[1], map[string]string{"foo": "bar"}, MTLS),
827
			},
828
		},
829
		{
830
			// service entry dns with target port
831
			externalSvc: dnsTargetPort,
832
			out: []*model.ServiceInstance{
833
				makeInstance(dnsTargetPort, "google.com", 8080, dnsTargetPort.Spec.(*networking.ServiceEntry).Ports[0], nil, PlainText),
834
			},
835
		},
836
		{
837
			// service entry tcp DNS
838
			externalSvc: tcpDNS,
839
			out: []*model.ServiceInstance{
840
				makeInstance(tcpDNS, "lon.google.com", 444, tcpDNS.Spec.(*networking.ServiceEntry).Ports[0], nil, MTLS),
841
				makeInstance(tcpDNS, "in.google.com", 444, tcpDNS.Spec.(*networking.ServiceEntry).Ports[0], nil, MTLS),
842
			},
843
		},
844
		{
845
			// service entry tcp static
846
			externalSvc: tcpStatic,
847
			out: []*model.ServiceInstance{
848
				makeInstance(tcpStatic, "1.1.1.1", 444, tcpStatic.Spec.(*networking.ServiceEntry).Ports[0], nil, MTLS),
849
				makeInstance(tcpStatic, "2.2.2.2", 444, tcpStatic.Spec.(*networking.ServiceEntry).Ports[0], nil, MTLS),
850
			},
851
		},
852
		{
853
			// service entry unix domain socket static
854
			externalSvc: udsLocal,
855
			out: []*model.ServiceInstance{
856
				makeInstance(udsLocal, "/test/sock", 0, udsLocal.Spec.(*networking.ServiceEntry).Ports[0], nil, MTLS),
857
			},
858
		},
859
	}
860

861
	for _, tt := range serviceInstanceTests {
862
		t.Run(strings.Join(tt.externalSvc.Spec.(*networking.ServiceEntry).Hosts, "_"), func(t *testing.T) {
863
			s := &Controller{}
864
			instances := s.convertServiceEntryToInstances(*tt.externalSvc, nil)
865
			sortServiceInstances(instances)
866
			sortServiceInstances(tt.out)
867
			if err := compare(t, instances, tt.out); err != nil {
868
				t.Fatalf("testcase: %v\n%v", tt.externalSvc.Name, err)
869
			}
870
		})
871
	}
872
}
873

874
func TestConvertWorkloadEntryToServiceInstances(t *testing.T) {
875
	labels := map[string]string{
876
		"app": "wle",
877
	}
878
	serviceInstanceTests := []struct {
879
		name      string
880
		wle       *networking.WorkloadEntry
881
		se        *config.Config
882
		clusterID cluster.ID
883
		out       []*model.ServiceInstance
884
	}{
885
		{
886
			name: "simple",
887
			wle: &networking.WorkloadEntry{
888
				Address: "1.1.1.1",
889
				Labels:  labels,
890
			},
891
			se: selector,
892
			out: []*model.ServiceInstance{
893
				makeInstance(selector, "1.1.1.1", 444, selector.Spec.(*networking.ServiceEntry).Ports[0], labels, PlainText),
894
				makeInstance(selector, "1.1.1.1", 445, selector.Spec.(*networking.ServiceEntry).Ports[1], labels, PlainText),
895
			},
896
		},
897
		{
898
			name: "mtls",
899
			wle: &networking.WorkloadEntry{
900
				Address:        "1.1.1.1",
901
				Labels:         labels,
902
				ServiceAccount: "default",
903
			},
904
			se: selector,
905
			out: []*model.ServiceInstance{
906
				makeInstanceWithServiceAccount(selector, "1.1.1.1", 444, selector.Spec.(*networking.ServiceEntry).Ports[0], labels, "default"),
907
				makeInstanceWithServiceAccount(selector, "1.1.1.1", 445, selector.Spec.(*networking.ServiceEntry).Ports[1], labels, "default"),
908
			},
909
		},
910
		{
911
			name: "replace-port",
912
			wle: &networking.WorkloadEntry{
913
				Address: "1.1.1.1",
914
				Labels:  labels,
915
				Ports: map[string]uint32{
916
					"http-445": 8080,
917
				},
918
			},
919
			se: selector,
920
			out: []*model.ServiceInstance{
921
				makeInstance(selector, "1.1.1.1", 444, selector.Spec.(*networking.ServiceEntry).Ports[0], labels, PlainText),
922
				makeInstance(selector, "1.1.1.1", 8080, selector.Spec.(*networking.ServiceEntry).Ports[1], labels, PlainText),
923
			},
924
		},
925
		{
926
			name: "augment label",
927
			wle: &networking.WorkloadEntry{
928
				Address:        "1.1.1.1",
929
				Labels:         labels,
930
				Locality:       "region1/zone1/sunzone1",
931
				Network:        "network1",
932
				ServiceAccount: "default",
933
			},
934
			se:        selector,
935
			clusterID: "fakeCluster",
936
			out: []*model.ServiceInstance{
937
				makeInstanceWithServiceAccount(selector, "1.1.1.1", 444, selector.Spec.(*networking.ServiceEntry).Ports[0], labels, "default"),
938
				makeInstanceWithServiceAccount(selector, "1.1.1.1", 445, selector.Spec.(*networking.ServiceEntry).Ports[1], labels, "default"),
939
			},
940
		},
941
	}
942

943
	for _, tt := range serviceInstanceTests {
944
		t.Run(tt.name, func(t *testing.T) {
945
			services := convertServices(*tt.se)
946
			s := &Controller{}
947
			instances := s.convertWorkloadEntryToServiceInstances(tt.wle, services, tt.se.Spec.(*networking.ServiceEntry), &configKey{}, tt.clusterID)
948
			sortServiceInstances(instances)
949
			sortServiceInstances(tt.out)
950

951
			if tt.wle.Locality != "" || tt.clusterID != "" || tt.wle.Network != "" {
952
				for _, serviceInstance := range tt.out {
953
					serviceInstance.Endpoint.Locality = model.Locality{
954
						Label:     tt.wle.Locality,
955
						ClusterID: tt.clusterID,
956
					}
957
					serviceInstance.Endpoint.Network = network.ID(tt.wle.Network)
958
					serviceInstance.Endpoint.Labels = labelutil.AugmentLabels(serviceInstance.Endpoint.Labels, tt.clusterID, tt.wle.Locality, "", network.ID(tt.wle.Network))
959
				}
960
			}
961

962
			if err := compare(t, instances, tt.out); err != nil {
963
				t.Fatal(err)
964
			}
965
		})
966
	}
967
}
968

969
func TestConvertWorkloadEntryToWorkloadInstance(t *testing.T) {
970
	workloadLabel := map[string]string{
971
		"app": "wle",
972
	}
973

974
	clusterID := "fakeCluster"
975
	expectedLabel := map[string]string{
976
		"app":                       "wle",
977
		"topology.istio.io/cluster": clusterID,
978
	}
979

980
	workloadInstanceTests := []struct {
981
		name           string
982
		getNetworkIDCb func(IP string, labels labels.Instance) network.ID
983
		wle            config.Config
984
		out            *model.WorkloadInstance
985
	}{
986
		{
987
			name: "simple",
988
			wle: config.Config{
989
				Meta: config.Meta{
990
					Namespace: "ns1",
991
				},
992
				Spec: &networking.WorkloadEntry{
993
					Address: "1.1.1.1",
994
					Labels:  workloadLabel,
995
					Ports: map[string]uint32{
996
						"http": 80,
997
					},
998
					ServiceAccount: "scooby",
999
				},
1000
			},
1001
			out: &model.WorkloadInstance{
1002
				Namespace: "ns1",
1003
				Kind:      model.WorkloadEntryKind,
1004
				Endpoint: &model.IstioEndpoint{
1005
					Labels:         expectedLabel,
1006
					Address:        "1.1.1.1",
1007
					ServiceAccount: "spiffe://cluster.local/ns/ns1/sa/scooby",
1008
					TLSMode:        "istio",
1009
					Namespace:      "ns1",
1010
					Locality: model.Locality{
1011
						ClusterID: cluster.ID(clusterID),
1012
					},
1013
				},
1014
				PortMap: map[string]uint32{
1015
					"http": 80,
1016
				},
1017
			},
1018
		},
1019
		{
1020
			name: "simple - tls mode disabled",
1021
			wle: config.Config{
1022
				Meta: config.Meta{
1023
					Namespace: "ns1",
1024
				},
1025
				Spec: &networking.WorkloadEntry{
1026
					Address: "1.1.1.1",
1027
					Labels: map[string]string{
1028
						"security.istio.io/tlsMode": "disabled",
1029
					},
1030
					Ports: map[string]uint32{
1031
						"http": 80,
1032
					},
1033
					ServiceAccount: "scooby",
1034
				},
1035
			},
1036
			out: &model.WorkloadInstance{
1037
				Namespace: "ns1",
1038
				Kind:      model.WorkloadEntryKind,
1039
				Endpoint: &model.IstioEndpoint{
1040
					Labels: map[string]string{
1041
						"security.istio.io/tlsMode": "disabled",
1042
						"topology.istio.io/cluster": clusterID,
1043
					},
1044
					Address:        "1.1.1.1",
1045
					ServiceAccount: "spiffe://cluster.local/ns/ns1/sa/scooby",
1046
					TLSMode:        "disabled",
1047
					Namespace:      "ns1",
1048
					Locality: model.Locality{
1049
						ClusterID: cluster.ID(clusterID),
1050
					},
1051
				},
1052
				PortMap: map[string]uint32{
1053
					"http": 80,
1054
				},
1055
			},
1056
		},
1057
		{
1058
			name: "unix domain socket",
1059
			wle: config.Config{
1060
				Meta: config.Meta{
1061
					Namespace: "ns1",
1062
				},
1063
				Spec: &networking.WorkloadEntry{
1064
					Address:        "unix://foo/bar",
1065
					ServiceAccount: "scooby",
1066
				},
1067
			},
1068
			out: &model.WorkloadInstance{
1069
				Namespace: "ns1",
1070
				Kind:      model.WorkloadEntryKind,
1071
				Endpoint: &model.IstioEndpoint{
1072
					Labels: map[string]string{
1073
						"topology.istio.io/cluster": clusterID,
1074
					},
1075
					Address:        "unix://foo/bar",
1076
					ServiceAccount: "spiffe://cluster.local/ns/ns1/sa/scooby",
1077
					TLSMode:        "istio",
1078
					Namespace:      "ns1",
1079
					Locality: model.Locality{
1080
						ClusterID: cluster.ID(clusterID),
1081
					},
1082
				},
1083
				DNSServiceEntryOnly: true,
1084
			},
1085
		},
1086
		{
1087
			name: "DNS address",
1088
			wle: config.Config{
1089
				Meta: config.Meta{
1090
					Namespace: "ns1",
1091
				},
1092
				Spec: &networking.WorkloadEntry{
1093
					Address:        "scooby.com",
1094
					ServiceAccount: "scooby",
1095
				},
1096
			},
1097
			out: &model.WorkloadInstance{
1098
				Namespace: "ns1",
1099
				Kind:      model.WorkloadEntryKind,
1100
				Endpoint: &model.IstioEndpoint{
1101
					Labels: map[string]string{
1102
						"topology.istio.io/cluster": clusterID,
1103
					},
1104
					Address:        "scooby.com",
1105
					ServiceAccount: "spiffe://cluster.local/ns/ns1/sa/scooby",
1106
					TLSMode:        "istio",
1107
					Namespace:      "ns1",
1108
					Locality: model.Locality{
1109
						ClusterID: cluster.ID(clusterID),
1110
					},
1111
				},
1112
				DNSServiceEntryOnly: true,
1113
			},
1114
		},
1115
		{
1116
			name: "metadata labels only",
1117
			wle: config.Config{
1118
				Meta: config.Meta{
1119
					Labels:    workloadLabel,
1120
					Namespace: "ns1",
1121
				},
1122
				Spec: &networking.WorkloadEntry{
1123
					Address: "1.1.1.1",
1124
					Ports: map[string]uint32{
1125
						"http": 80,
1126
					},
1127
					ServiceAccount: "scooby",
1128
				},
1129
			},
1130
			out: &model.WorkloadInstance{
1131
				Namespace: "ns1",
1132
				Kind:      model.WorkloadEntryKind,
1133
				Endpoint: &model.IstioEndpoint{
1134
					Labels:         expectedLabel,
1135
					Address:        "1.1.1.1",
1136
					ServiceAccount: "spiffe://cluster.local/ns/ns1/sa/scooby",
1137
					TLSMode:        "istio",
1138
					Namespace:      "ns1",
1139
					Locality: model.Locality{
1140
						ClusterID: cluster.ID(clusterID),
1141
					},
1142
				},
1143
				PortMap: map[string]uint32{
1144
					"http": 80,
1145
				},
1146
			},
1147
		},
1148
		{
1149
			name: "labels merge",
1150
			wle: config.Config{
1151
				Meta: config.Meta{
1152
					Namespace: "ns1",
1153
					Labels: map[string]string{
1154
						"my-label": "bar",
1155
					},
1156
				},
1157
				Spec: &networking.WorkloadEntry{
1158
					Address: "1.1.1.1",
1159
					Labels:  workloadLabel,
1160
					Ports: map[string]uint32{
1161
						"http": 80,
1162
					},
1163
					ServiceAccount: "scooby",
1164
				},
1165
			},
1166
			out: &model.WorkloadInstance{
1167
				Namespace: "ns1",
1168
				Kind:      model.WorkloadEntryKind,
1169
				Endpoint: &model.IstioEndpoint{
1170
					Labels: map[string]string{
1171
						"my-label":                  "bar",
1172
						"app":                       "wle",
1173
						"topology.istio.io/cluster": clusterID,
1174
					},
1175
					Address:        "1.1.1.1",
1176
					ServiceAccount: "spiffe://cluster.local/ns/ns1/sa/scooby",
1177
					TLSMode:        "istio",
1178
					Namespace:      "ns1",
1179
					Locality: model.Locality{
1180
						ClusterID: cluster.ID(clusterID),
1181
					},
1182
				},
1183
				PortMap: map[string]uint32{
1184
					"http": 80,
1185
				},
1186
			},
1187
		},
1188
		{
1189
			name: "augment labels",
1190
			wle: config.Config{
1191
				Meta: config.Meta{
1192
					Namespace: "ns1",
1193
				},
1194
				Spec: &networking.WorkloadEntry{
1195
					Address: "1.1.1.1",
1196
					Labels:  workloadLabel,
1197
					Ports: map[string]uint32{
1198
						"http": 80,
1199
					},
1200
					Locality:       "region1/zone1/subzone1",
1201
					Network:        "network1",
1202
					ServiceAccount: "scooby",
1203
				},
1204
			},
1205
			out: &model.WorkloadInstance{
1206
				Namespace: "ns1",
1207
				Kind:      model.WorkloadEntryKind,
1208
				Endpoint: &model.IstioEndpoint{
1209
					Labels: map[string]string{
1210
						"app":                           "wle",
1211
						"topology.kubernetes.io/region": "region1",
1212
						"topology.kubernetes.io/zone":   "zone1",
1213
						"topology.istio.io/subzone":     "subzone1",
1214
						"topology.istio.io/network":     "network1",
1215
						"topology.istio.io/cluster":     clusterID,
1216
					},
1217
					Address: "1.1.1.1",
1218
					Network: "network1",
1219
					Locality: model.Locality{
1220
						Label:     "region1/zone1/subzone1",
1221
						ClusterID: cluster.ID(clusterID),
1222
					},
1223
					ServiceAccount: "spiffe://cluster.local/ns/ns1/sa/scooby",
1224
					TLSMode:        "istio",
1225
					Namespace:      "ns1",
1226
				},
1227
				PortMap: map[string]uint32{
1228
					"http": 80,
1229
				},
1230
			},
1231
		},
1232
		{
1233
			name: "augment labels: networkID get from cb",
1234
			wle: config.Config{
1235
				Meta: config.Meta{
1236
					Namespace: "ns1",
1237
				},
1238
				Spec: &networking.WorkloadEntry{
1239
					Address: "1.1.1.1",
1240
					Labels:  workloadLabel,
1241
					Ports: map[string]uint32{
1242
						"http": 80,
1243
					},
1244
					Locality:       "region1/zone1/subzone1",
1245
					ServiceAccount: "scooby",
1246
				},
1247
			},
1248
			getNetworkIDCb: func(IP string, labels labels.Instance) network.ID {
1249
				return "cb-network1"
1250
			},
1251
			out: &model.WorkloadInstance{
1252
				Namespace: "ns1",
1253
				Kind:      model.WorkloadEntryKind,
1254
				Endpoint: &model.IstioEndpoint{
1255
					Labels: map[string]string{
1256
						"app":                           "wle",
1257
						"topology.kubernetes.io/region": "region1",
1258
						"topology.kubernetes.io/zone":   "zone1",
1259
						"topology.istio.io/subzone":     "subzone1",
1260
						"topology.istio.io/network":     "cb-network1",
1261
						"topology.istio.io/cluster":     clusterID,
1262
					},
1263
					Address: "1.1.1.1",
1264
					Locality: model.Locality{
1265
						Label:     "region1/zone1/subzone1",
1266
						ClusterID: cluster.ID(clusterID),
1267
					},
1268
					ServiceAccount: "spiffe://cluster.local/ns/ns1/sa/scooby",
1269
					TLSMode:        "istio",
1270
					Namespace:      "ns1",
1271
				},
1272
				PortMap: map[string]uint32{
1273
					"http": 80,
1274
				},
1275
			},
1276
		},
1277
	}
1278

1279
	for _, tt := range workloadInstanceTests {
1280
		t.Run(tt.name, func(t *testing.T) {
1281
			s := &Controller{networkIDCallback: tt.getNetworkIDCb}
1282
			instance := s.convertWorkloadEntryToWorkloadInstance(tt.wle, cluster.ID(clusterID))
1283
			if err := compare(t, instance, tt.out); err != nil {
1284
				t.Fatal(err)
1285
			}
1286
		})
1287
	}
1288
}
1289

1290
func compare[T any](t testing.TB, actual, expected T) error {
1291
	return util.Compare(jsonBytes(t, actual), jsonBytes(t, expected))
1292
}
1293

1294
func jsonBytes(t testing.TB, v any) []byte {
1295
	data, err := json.MarshalIndent(v, "", " ")
1296
	if err != nil {
1297
		t.Fatal(t)
1298
	}
1299
	return data
1300
}
1301

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

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

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

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