github.com/cilium/cilium@v1.16.2/pkg/endpointmanager/endpointsynchronizer_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package endpointmanager 5 6 import ( 7 "fmt" 8 "net" 9 "testing" 10 11 "github.com/sirupsen/logrus" 12 "github.com/stretchr/testify/assert" 13 v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 14 "k8s.io/apimachinery/pkg/types" 15 16 "github.com/cilium/cilium/pkg/endpoint" 17 v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" 18 slim_corev1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/core/v1" 19 "github.com/cilium/cilium/pkg/node" 20 ) 21 22 func Test_updateCEPUID(t *testing.T) { 23 podWithHostIP := func(hostIP string) *slim_corev1.Pod { 24 return &slim_corev1.Pod{ 25 Status: slim_corev1.PodStatus{ 26 HostIP: hostIP, 27 }, 28 } 29 } 30 epWithUID := func(uid string, pod *slim_corev1.Pod) *endpoint.Endpoint { 31 ep := &endpoint.Endpoint{} 32 ep.SetPod(pod) 33 ep.SetCiliumEndpointUID(types.UID(uid)) 34 return ep 35 } 36 testIP := "1.2.3.4" 37 someUID := func(s string) *types.UID { 38 id := types.UID(s) 39 return &id 40 } 41 for name, test := range map[string]struct { 42 err error 43 cep *v2.CiliumEndpoint 44 ep *endpoint.Endpoint 45 nodeIP string 46 expectedEPUID *types.UID 47 }{ 48 // In this test, our CEP has a UID that is different from the local Endpoint. 49 // This means that the CEP is not owned by this EP. 50 // Ownership should fail due to Endpoint not having a pod. 51 // This condition is typically triggered when the pod is deleted. 52 "no pod": { 53 ep: epWithUID("000", nil), 54 err: fmt.Errorf("no pod"), 55 nodeIP: testIP, 56 cep: &v2.CiliumEndpoint{ 57 ObjectMeta: v1.ObjectMeta{ 58 UID: "111", // Different UID from the local Endpoint. 59 }, 60 }, 61 }, 62 "CiliumEndpoint not local": { 63 // The CEP is explicitly not local (i.e the CEP's pod's hostIP doesn't match the nodeIP). 64 ep: epWithUID("1234", podWithHostIP(testIP)), 65 nodeIP: "4.3.2.1", 66 err: fmt.Errorf("is not local"), 67 cep: &v2.CiliumEndpoint{ 68 ObjectMeta: v1.ObjectMeta{UID: "1111"}, 69 }, 70 }, 71 "CiliumEndpoint not local, but already owned": { 72 // The CEP is explicitly not local. But the CEP is already owned by the endpoint. 73 // So ownership should proceed without error. 74 ep: epWithUID("000", podWithHostIP("4.3.2.1")), // matches CEP. 75 nodeIP: testIP, 76 cep: &v2.CiliumEndpoint{ 77 ObjectMeta: v1.ObjectMeta{UID: "000"}, 78 }, 79 }, 80 "ciliumendpoint already exists": { 81 // CEP already exists, on the same node, we cannot take ownership of it 82 // due to differing UID ref. 83 // 84 // This would be the case where two endpoint sync controllers are running for 85 // a Pod with the same namespace/name on the same Agent, so we'd have to wait 86 // until the other controller terminates and cleans up the CEP. 87 err: fmt.Errorf("did not match CEP UID"), 88 expectedEPUID: someUID("b"), 89 ep: epWithUID("b", podWithHostIP(testIP)), 90 nodeIP: testIP, 91 cep: &v2.CiliumEndpoint{ 92 ObjectMeta: v1.ObjectMeta{UID: types.UID("a")}, 93 }, 94 }, 95 // This is the normal case of taking ownership. 96 // Note that this also happens when the nodeIP changes during a reboot 97 // but the endpoint snapshot is lost on reboot. The endpoint UID will 98 // remain empty, but the CEP object will have a UID and a wrong nodeIP. 99 // It is to counter this case that we check the pods hostIP against the 100 // nodeIP instaed of the CEP's node IP. 101 "take ownership of cep due to empty CiliumEndpointUID ref": { 102 ep: epWithUID("", podWithHostIP(testIP)), 103 nodeIP: testIP, 104 expectedEPUID: someUID("a"), 105 cep: &v2.CiliumEndpoint{ 106 ObjectMeta: v1.ObjectMeta{UID: types.UID("a")}, 107 Status: v2.EndpointStatus{ 108 Networking: &v2.EndpointNetworking{ 109 NodeIP: "4.5.6.7", 110 }, 111 }, 112 }, 113 }, 114 } { 115 t.Run(name, func(t *testing.T) { 116 assert := assert.New(t) 117 var err error 118 node.WithTestLocalNodeStore(func() { 119 node.UpdateLocalNodeInTest(func(n *node.LocalNode) { 120 n.SetNodeInternalIP(net.ParseIP(test.nodeIP)) 121 }) 122 err = updateCEPUID(logrus.StandardLogger().WithFields(logrus.Fields{}), test.ep, test.cep) 123 }) 124 if test.err == nil { 125 assert.NoError(err) 126 } else { 127 assert.ErrorContains(err, test.err.Error()) 128 } 129 if test.expectedEPUID != nil { 130 assert.Equal(*test.expectedEPUID, test.ep.GetCiliumEndpointUID()) 131 } 132 }) 133 134 } 135 }