istio
351 строка · 12.9 Кб
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
15package ambient16
17import (18"net/netip"19"testing"20
21corev1 "k8s.io/api/core/v1"22
23"istio.io/istio/pilot/pkg/features"24"istio.io/istio/pilot/pkg/model"25"istio.io/istio/pkg/test"26"istio.io/istio/pkg/test/util/assert"27"istio.io/istio/pkg/workloadapi"28)
29
30func TestAmbientIndex_ServiceEntry(t *testing.T) {31s := newAmbientTestServer(t, testC, testNW)32
33// test code path where service entry creates a workload entry via `ServiceEntry.endpoints`34// and the inlined WE has a port override35s.addServiceEntry(t, "se.istio.io", []string{"240.240.23.45"}, "name1", testNS, nil, []string{"127.0.0.1"})36s.assertEvent(t, s.seIPXdsName("name1", "127.0.0.1"), "ns1/se.istio.io")37s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name1")38assert.Equal(t, s.lookup(s.addrXdsName("127.0.0.1")), []model.AddressInfo{{39Address: &workloadapi.Address{40Type: &workloadapi.Address_Workload{41Workload: &workloadapi.Workload{42Uid: s.seIPXdsName("name1", "127.0.0.1"),43Name: "name1",44Namespace: testNS,45Addresses: [][]byte{parseIP("127.0.0.1")},46Node: "",47Network: testNW,48CanonicalName: "name1",49CanonicalRevision: "latest",50WorkloadType: workloadapi.WorkloadType_POD,51WorkloadName: "name1",52Services: map[string]*workloadapi.PortList{53"ns1/se.istio.io": {54Ports: []*workloadapi.Port{55{56ServicePort: 80,57TargetPort: 8081, // port is overridden by inlined WE port58},59},60},61},62ClusterId: testC,63},64},65},66}})67
68s.deleteServiceEntry(t, "name1", testNS)69s.assertEvent(t, s.seIPXdsName("name1", "127.0.0.1"), "ns1/se.istio.io")70assert.Equal(t, s.lookup(s.addrXdsName("127.0.0.1")), nil)71s.clearEvents()72
73// workload entry that has an address of future pod will be dropped from result once pod is added74s.addWorkloadEntries(t, "140.140.0.10", "name0", "sa1", map[string]string{"app": "a"})75s.assertEvent(t, s.wleXdsName("name0"))76// workload entry is included in the result until pod1 with the same address below is added77s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "name0")78// lookup by address should return the workload entry's address info79assert.Equal(t, s.lookup(s.addrXdsName("140.140.0.10")), []model.AddressInfo{{80Address: &workloadapi.Address{81Type: &workloadapi.Address_Workload{82Workload: &workloadapi.Workload{83Uid: s.wleXdsName("name0"),84Name: "name0",85Namespace: testNS,86Addresses: [][]byte{parseIP("140.140.0.10")},87Network: testNW,88CanonicalName: "a",89CanonicalRevision: "latest",90ServiceAccount: "sa1",91WorkloadType: workloadapi.WorkloadType_POD,92WorkloadName: "name0",93ClusterId: testC,94},95},96},97}})98
99// test code path where service entry selects workloads via `ServiceEntry.workloadSelector`100s.addPods(t, "140.140.0.10", "pod1", "sa1", map[string]string{"app": "a"}, nil, true, corev1.PodRunning)101s.assertEvent(t, s.podXdsName("pod1"))102
103// lookup by address should return the pod's address info (ignore the workload entry with similar address)104assert.Equal(t, s.lookup(s.addrXdsName("140.140.0.10")), []model.AddressInfo{{105Address: &workloadapi.Address{106Type: &workloadapi.Address_Workload{107Workload: &workloadapi.Workload{108Uid: s.podXdsName("pod1"),109Name: "pod1",110Namespace: testNS,111Addresses: [][]byte{parseIP("140.140.0.10")},112Network: testNW,113ClusterId: testC,114Node: "node1",115CanonicalName: "a",116CanonicalRevision: "latest",117ServiceAccount: "sa1",118WorkloadType: workloadapi.WorkloadType_POD,119WorkloadName: "pod1",120},121},122},123}})124
125s.addPods(t, "140.140.0.11", "pod2", "sa1", map[string]string{"app": "other"}, nil, true, corev1.PodRunning)126s.assertEvent(t, s.podXdsName("pod2"))127s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "pod1", "pod2")128s.addWorkloadEntries(t, "240.240.34.56", "name1", "sa1", map[string]string{"app": "a"})129s.assertEvent(t, s.wleXdsName("name1"))130s.addWorkloadEntries(t, "240.240.34.57", "name2", "sa1", map[string]string{"app": "other"})131s.assertEvent(t, s.wleXdsName("name2"))132s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "pod1", "pod2", "name1", "name2")133
134s.addWorkloadEntries(t, "140.140.0.11", "name3", "sa1", map[string]string{"app": "other"})135s.assertEvent(t, s.wleXdsName("name3"))136s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "pod1", "pod2", "name1", "name2")137
138// a service entry should not be able to select across namespaces139s.addServiceEntry(t, "mismatched.istio.io", []string{"240.240.23.45"}, "name1", "mismatched-ns", map[string]string{"app": "a"}, nil)140s.assertEvent(t, "mismatched-ns/mismatched.istio.io")141assert.Equal(t, s.lookup(s.addrXdsName("140.140.0.10")), []model.AddressInfo{{142Address: &workloadapi.Address{143Type: &workloadapi.Address_Workload{144Workload: &workloadapi.Workload{145Uid: s.podXdsName("pod1"),146Name: "pod1",147Namespace: testNS,148Addresses: [][]byte{parseIP("140.140.0.10")},149Node: "node1",150Network: testNW,151CanonicalName: "a",152CanonicalRevision: "latest",153ServiceAccount: "sa1",154WorkloadType: workloadapi.WorkloadType_POD,155WorkloadName: "pod1",156Services: nil, // should not be selected by the mismatched service entry157ClusterId: testC,158},159},160},161}})162assert.Equal(t, s.lookup(s.addrXdsName("240.240.34.56")), []model.AddressInfo{{163Address: &workloadapi.Address{164Type: &workloadapi.Address_Workload{165Workload: &workloadapi.Workload{166Uid: s.wleXdsName("name1"),167Name: "name1",168Namespace: testNS,169Addresses: [][]byte{parseIP("240.240.34.56")},170Node: "",171Network: testNW,172CanonicalName: "a",173CanonicalRevision: "latest",174ServiceAccount: "sa1",175WorkloadType: workloadapi.WorkloadType_POD,176WorkloadName: "name1",177Services: nil, // should not be selected by the mismatched service entry178ClusterId: testC,179},180},181},182}})183
184s.addServiceEntry(t, "se.istio.io", []string{"240.240.23.45"}, "name1", testNS, map[string]string{"app": "a"}, nil)185s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "pod1", "pod2", "name1", "name2")186// we should see an update for the workloads selected by the service entry187// do not expect event for pod2 since it is not selected by the service entry188s.assertEvent(t, s.podXdsName("pod1"), s.wleXdsName("name0"), s.wleXdsName("name1"), "ns1/se.istio.io")189
190assert.Equal(t, s.lookup(s.addrXdsName("140.140.0.10")), []model.AddressInfo{{191Address: &workloadapi.Address{192Type: &workloadapi.Address_Workload{193Workload: &workloadapi.Workload{194Uid: s.podXdsName("pod1"),195Name: "pod1",196Namespace: testNS,197Addresses: [][]byte{parseIP("140.140.0.10")},198Node: "node1",199Network: testNW,200CanonicalName: "a",201CanonicalRevision: "latest",202ServiceAccount: "sa1",203WorkloadType: workloadapi.WorkloadType_POD,204WorkloadName: "pod1",205Services: map[string]*workloadapi.PortList{206"ns1/se.istio.io": {207Ports: []*workloadapi.Port{208{209ServicePort: 80,210TargetPort: 8080,211},212},213},214},215ClusterId: testC,216},217},218},219}})220
221assert.Equal(t, s.lookup(s.addrXdsName("140.140.0.11")), []model.AddressInfo{{222Address: &workloadapi.Address{223Type: &workloadapi.Address_Workload{224Workload: &workloadapi.Workload{225Uid: s.podXdsName("pod2"),226Name: "pod2",227Namespace: testNS,228Addresses: [][]byte{parseIP("140.140.0.11")},229Node: "node1",230Network: testNW,231ClusterId: testC,232CanonicalName: "other",233CanonicalRevision: "latest",234ServiceAccount: "sa1",235WorkloadType: workloadapi.WorkloadType_POD,236WorkloadName: "pod2",237Services: nil, // labels don't match workloadSelector, this should be nil238},239},240},241}})242
243assert.Equal(t, s.lookup(s.addrXdsName("240.240.34.56")), []model.AddressInfo{{244Address: &workloadapi.Address{245Type: &workloadapi.Address_Workload{246Workload: &workloadapi.Workload{247Uid: s.wleXdsName("name1"),248Name: "name1",249Namespace: testNS,250Addresses: [][]byte{parseIP("240.240.34.56")},251Node: "",252Network: testNW,253CanonicalName: "a",254CanonicalRevision: "latest",255ServiceAccount: "sa1",256WorkloadType: workloadapi.WorkloadType_POD,257WorkloadName: "name1",258Services: map[string]*workloadapi.PortList{259"ns1/se.istio.io": {260Ports: []*workloadapi.Port{261{262ServicePort: 80,263TargetPort: 8080,264},265},266},267},268ClusterId: testC,269},270},271},272}})273
274s.deleteServiceEntry(t, "name1", testNS)275s.assertWorkloads(t, "", workloadapi.WorkloadStatus_HEALTHY, "pod1", "pod2", "name1", "name2")276s.assertUniqueWorkloads(t)277// we should see an update for the workloads selected by the service entry278s.assertEvent(t, s.podXdsName("pod1"), s.wleXdsName("name0"), s.wleXdsName("name1"), "ns1/se.istio.io")279assert.Equal(t, s.lookup(s.addrXdsName("140.140.0.10")), []model.AddressInfo{{280Address: &workloadapi.Address{281Type: &workloadapi.Address_Workload{282Workload: &workloadapi.Workload{283Uid: s.podXdsName("pod1"),284Name: "pod1",285Namespace: testNS,286Addresses: [][]byte{parseIP("140.140.0.10")},287Node: "node1",288Network: testNW,289ClusterId: testC,290CanonicalName: "a",291CanonicalRevision: "latest",292ServiceAccount: "sa1",293WorkloadType: workloadapi.WorkloadType_POD,294WorkloadName: "pod1",295Services: nil, // vips for pod1 should be gone now296},297},298},299}})300
301assert.Equal(t, s.lookup(s.addrXdsName("240.240.34.56")), []model.AddressInfo{{302Address: &workloadapi.Address{303Type: &workloadapi.Address_Workload{304Workload: &workloadapi.Workload{305Uid: s.wleXdsName("name1"),306Name: "name1",307Namespace: testNS,308Addresses: [][]byte{parseIP("240.240.34.56")},309Node: "",310Network: testNW,311CanonicalName: "a",312CanonicalRevision: "latest",313ServiceAccount: "sa1",314WorkloadType: workloadapi.WorkloadType_POD,315WorkloadName: "name1",316Services: nil, // vips for workload entry 1 should be gone now317ClusterId: testC,318},319},320},321}})322}
323
324func TestAmbientIndex_ServiceEntry_DisableK8SServiceSelectWorkloadEntries(t *testing.T) {325test.SetForTest(t, &features.EnableK8SServiceSelectWorkloadEntries, false)326s := newAmbientTestServer(t, testC, testNW)327
328s.addPods(t, "140.140.0.10", "pod1", "sa1", map[string]string{"app": "a"}, nil, true, corev1.PodRunning)329s.assertEvent(t, s.podXdsName("pod1"))330s.addPods(t, "140.140.0.11", "pod2", "sa1", map[string]string{"app": "other"}, nil, true, corev1.PodRunning)331s.assertEvent(t, s.podXdsName("pod2"))332s.addWorkloadEntries(t, "240.240.34.56", "name1", "sa1", map[string]string{"app": "a"})333s.assertEvent(t, s.wleXdsName("name1"))334s.addWorkloadEntries(t, "240.240.34.57", "name2", "sa1", map[string]string{"app": "other"})335s.assertEvent(t, s.wleXdsName("name2"))336s.addServiceEntry(t, "se.istio.io", []string{"240.240.23.45"}, "name1", testNS, map[string]string{"app": "a"}, nil)337s.assertEvent(t, s.podXdsName("pod1"), s.wleXdsName("name1"), "ns1/se.istio.io")338s.clearEvents()339
340// Setting the PILOT_ENABLE_K8S_SELECT_WORKLOAD_ENTRIES to false shouldn't affect the workloads selected by the service341// entry342s.assertWorkloads(t, s.addrXdsName("240.240.23.45"), workloadapi.WorkloadStatus_HEALTHY, "pod1", "name1")343}
344
345func parseIP(ip string) []byte {346addr, err := netip.ParseAddr(ip)347if err != nil {348return nil349}350return addr.AsSlice()351}
352