]> git.feebdaed.xyz Git - 0xmirror/cilium.git/commitdiff
ztunnel: ensure xDS uses Kubernetes pod UID, not CEP UID
authorLouis DeLosSantos <louis.delos@isovalent.com>
Tue, 16 Dec 2025 15:31:13 +0000 (10:31 -0500)
committerLouis DeLosSantos <louis.delos@isovalent.com>
Thu, 18 Dec 2025 13:38:05 +0000 (13:38 +0000)
The xDS server was utilizing CiliumEndpoint UIDs while both ztunnel and
our ZDS implementation refer to Kubernetes pod UID.

We must make the K8s Pod UID available to xDS by way of the
CiliumEndpoint. Introduce the required plumbing to carry forward the
K8sUID into CiliumEndoint via the OwnerReference structure.

Signed-off-by: Louis DeLosSantos <louis.delos@isovalent.com>
pkg/k8s/factory_functions.go
pkg/k8s/factory_functions_test.go
pkg/ztunnel/xds/endpoint_event.go
pkg/ztunnel/xds/endpoint_event_test.go
pkg/ztunnel/xds/stream_processor_test.go

index f3c5c19991e57f8595e61bc65eee1f77b38e7022..288029f6fed6bd6398f69fe2309329833c6611e8 100644 (file)
@@ -142,6 +142,8 @@ func TransformToCiliumEndpoint(obj any) (any, error) {
                                // they are not used by the CEP handlers.
                                Labels:      nil,
                                Annotations: nil,
+                               // OwnerReferences is needed for ztunnel xDS to extract Pod UID.
+                               OwnerReferences: slim_metav1.SlimOwnerReferences(concreteObj.ObjectMeta.OwnerReferences),
                        },
                        Encryption: func() *cilium_v2.EncryptionSpec {
                                enc := concreteObj.Status.Encryption
@@ -178,6 +180,8 @@ func TransformToCiliumEndpoint(obj any) (any, error) {
                                        // they are not used by the CEP handlers.
                                        Labels:      nil,
                                        Annotations: nil,
+                                       // OwnerReferences is needed for ztunnel xDS to extract Pod UID.
+                                       OwnerReferences: slim_metav1.SlimOwnerReferences(ciliumEndpoint.ObjectMeta.OwnerReferences),
                                },
                                Encryption: func() *cilium_v2.EncryptionSpec {
                                        enc := ciliumEndpoint.Status.Encryption
index 760106188aae58595c5747760a1978157b7c6b3c..32b706103cdf07f62e184d35dc8a18a44beb4281 100644 (file)
@@ -1193,6 +1193,16 @@ func Test_TransformToCiliumEndpoint(t *testing.T) {
                                                // they are not used by the CEP handlers.
                                                Labels:      nil,
                                                Annotations: nil,
+                                               // OwnerReferences is preserved for ztunnel xDS to extract Pod UID.
+                                               OwnerReferences: []slim_metav1.OwnerReference{
+                                                       {
+                                                               Kind:       "Pod",
+                                                               APIVersion: "v1",
+                                                               Name:       "foo",
+                                                               UID:        "65dasd54d45",
+                                                               Controller: nil,
+                                                       },
+                                               },
                                        },
                                        Identity: &v2.EndpointIdentity{
                                                ID: 9654,
index bdcfbf917ea595e30e82ed3eee876123edf4e401..1581f7f116e45e1bdb579a291ca3e9952f968564 100644 (file)
@@ -62,13 +62,13 @@ func (c EndpointEventCollection) ToDeltaDiscoveryResponse() *v3.DeltaDiscoveryRe
                        // ztunnel uses a very stripped down representation of a Resource
                        // see: https://github.com/istio/ztunnel/blob/58cf2a0f943ffc23c32d889018428ddfa6175144/src/xds/client.rs#L773
                        res := &v3.Resource{
-                               Name:     string(event.UID),
+                               Name:     event.getPodUID(),
                                Resource: anyPBAddr,
                        }
 
                        createResources = append(createResources, res)
                case REMOVED:
-                       removedNames = append(removedNames, string(event.UID))
+                       removedNames = append(removedNames, event.getPodUID())
                }
        }
 
@@ -99,6 +99,18 @@ type EndpointEvent struct {
        *types.CiliumEndpoint
 }
 
+// getPodUID returns the Pod UID from the CiliumEndpoint's OwnerReferences.
+// CiliumEndpoints are owned by Pods, so the Pod UID is available in OwnerReferences.
+// This is consistent with the ZDS server which also uses Pod UIDs.
+func (e *EndpointEvent) getPodUID() string {
+       for _, ref := range e.OwnerReferences {
+               if ref.Kind == "Pod" {
+                       return string(ref.UID)
+               }
+       }
+       return ""
+}
+
 // ToXDSAddress transforms the embedded Endpoint into a XDS Address capable of
 // being used in a DeltaDiscoveryResponse.
 //
@@ -127,7 +139,7 @@ func (e *EndpointEvent) ToXDSAddress() (*pb.Address, error) {
        }
 
        w := &pb.Workload{
-               Uid: string(e.UID),
+               Uid: e.getPodUID(),
                // TODO(hemanthmalla) Convert this field to node name.
                // zTunnel will match this with it's own node name.
                Node:           e.Networking.NodeIP,
index ad9d116876c3bc10fbc147afa7fac3d13e59ff80..7528dcb95ec0315c68a9b6fb74e801d0bd46f9ab 100644 (file)
@@ -59,7 +59,8 @@ func TestEndpointEventToXDSAddress(t *testing.T) {
                require.NotNil(t, workload, "Address should contain Workload")
 
                // Validate all required field mappings from endpoint to workload
-               require.Equal(t, ep.K8sUID, workload.Uid, "Workload.Uid should match endpoint.K8sUID")
+               // The workload UID comes from OwnerReferences (Pod UID)
+               require.Equal(t, ep.K8sUID, workload.Uid, "Workload.Uid should match Pod UID from OwnerReferences")
                require.Equal(t, ep.K8sPodName, workload.Name, "Workload.Name should match endpoint.K8sPodName")
                require.Equal(t, ep.K8sNamespace, workload.Namespace, "Workload.Namespace should match endpoint.K8sNamespace")
                // TODO(hemanthmalla): Currently we're setting zTunnel node name to host IP due to lack of nodename in CEP.
@@ -123,7 +124,8 @@ func TestEndpointEventToXDSAddress(t *testing.T) {
                require.NotNil(t, workload, "Address should contain Workload")
 
                // Validate all required field mappings from endpoint to workload
-               require.Equal(t, ep.K8sUID, workload.Uid, "Workload.Uid should match endpoint.K8sUID")
+               // The workload UID comes from OwnerReferences (Pod UID)
+               require.Equal(t, ep.K8sUID, workload.Uid, "Workload.Uid should match Pod UID from OwnerReferences")
                require.Equal(t, ep.K8sPodName, workload.Name, "Workload.Name should match endpoint.K8sPodName")
                require.Equal(t, ep.K8sNamespace, workload.Namespace, "Workload.Namespace should match endpoint.K8sNamespace")
                // TODO(hemanthmalla): Currently we're setting zTunnel node name to host IP due to lack of nodename in CEP.
@@ -156,7 +158,12 @@ func endpointToCiliumEndpoint(ep *endpoint.Endpoint) *types.CiliumEndpoint {
                ObjectMeta: slim_metav1.ObjectMeta{
                        Name:      ep.K8sPodName,
                        Namespace: ep.K8sNamespace,
-                       UID:       apimachineryTypes.UID(ep.K8sUID),
+                       OwnerReferences: []slim_metav1.OwnerReference{
+                               {
+                                       Kind: "Pod",
+                                       UID:  apimachineryTypes.UID(ep.K8sUID),
+                               },
+                       },
                },
 
                Networking: &v2.EndpointNetworking{
index ef3b1d4a90c3ea65480f723bfb008df6b633a9a3..a33eed5d55f82edb8670a1298dc06e4c9b4056f8 100644 (file)
@@ -389,6 +389,7 @@ func TestStreamProcessorDeltaDiscoveryRequest(t *testing.T) {
                        return nil
                }
 
+               // These UIDs must match what MockEndpointEventSource.ListAllEndpoints returns
                expectedUIDs := []string{
                        "12345678-1234-1234-1234-123456789abc", // ep1
                        "87654321-4321-4321-4321-cba987654321", // ep2