func toZoneNetworkEndpointMap()

in pkg/neg/syncers/utils.go [222:301]


func toZoneNetworkEndpointMap(eds []negtypes.EndpointsData, zoneGetter negtypes.ZoneGetter, servicePortName string, podLister cache.Indexer, subsetLabels string, networkEndpointType negtypes.NetworkEndpointType) (map[string]negtypes.NetworkEndpointSet, negtypes.EndpointPodMap, error) {
	zoneNetworkEndpointMap := map[string]negtypes.NetworkEndpointSet{}
	networkEndpointPodMap := negtypes.EndpointPodMap{}
	if eds == nil {
		klog.Errorf("Endpoint object is nil")
		return zoneNetworkEndpointMap, networkEndpointPodMap, nil
	}
	var foundMatchingPort bool
	for _, ed := range eds {
		matchPort := ""
		// service spec allows target Port to be a named Port.
		// support both explicit Port and named Port.
		for _, port := range ed.Ports {
			if port.Name == servicePortName {
				matchPort = strconv.Itoa(int(port.Port))
				break
			}
		}

		// subset does not contain target Port
		if len(matchPort) == 0 {
			continue
		}
		foundMatchingPort = true

		for _, endpointAddress := range ed.Addresses {
			// Apply the selector if Istio:DestinationRule subset labels provided.
			if subsetLabels != "" {
				if endpointAddress.TargetRef == nil || endpointAddress.TargetRef.Kind != "Pod" {
					klog.V(2).Infof("Endpoint %q in Endpoints %s/%s does not have a Pod as the TargetRef object. Skipping", endpointAddress.Addresses, ed.Meta.Namespace, ed.Meta.Name)
					continue
				}
				// Skip if the endpoint's pod not matching the subset lables.
				if !shouldPodBeInDestinationRuleSubset(podLister, endpointAddress.TargetRef.Namespace, endpointAddress.TargetRef.Name, subsetLabels) {
					continue
				}
			}
			if endpointAddress.NodeName == nil {
				klog.V(2).Infof("Endpoint %q in Endpoints %s/%s does not have an associated node. Skipping", endpointAddress.Addresses, ed.Meta.Namespace, ed.Meta.Name)
				continue
			}
			if endpointAddress.TargetRef == nil {
				klog.V(2).Infof("Endpoint %q in Endpoints %s/%s does not have an associated pod. Skipping", endpointAddress.Addresses, ed.Meta.Namespace, ed.Meta.Name)
				continue
			}
			zone, err := zoneGetter.GetZoneForNode(*endpointAddress.NodeName)
			if err != nil {
				return nil, nil, fmt.Errorf("failed to retrieve associated zone of node %q: %w", *endpointAddress.NodeName, err)
			}
			if zoneNetworkEndpointMap[zone] == nil {
				zoneNetworkEndpointMap[zone] = negtypes.NewNetworkEndpointSet()
			}

			// TODO: This check and EndpointsData.Ready field may be deleted once Endpoints support is removed.
			// The purpose of this check is to handle endpoints in terminating state.
			// The Endpoints API doesn't have terminating field. Terminating endpoints are marked as not ready.
			// This check support this case. For not ready endpoints it checks if the endpoint is not yet ready or terminating.
			// The EndpointSlices API has terminating field which solves this problem.
			if endpointAddress.Ready || shouldPodBeInNeg(podLister, endpointAddress.TargetRef.Namespace, endpointAddress.TargetRef.Name) {
				for _, address := range endpointAddress.Addresses {
					networkEndpoint := negtypes.NetworkEndpoint{IP: address, Port: matchPort, Node: *endpointAddress.NodeName}
					if networkEndpointType == negtypes.NonGCPPrivateEndpointType {
						// Non-GCP network endpoints don't have associated nodes.
						networkEndpoint.Node = ""
					}
					zoneNetworkEndpointMap[zone].Insert(networkEndpoint)
					networkEndpointPodMap[networkEndpoint] = types.NamespacedName{Namespace: endpointAddress.TargetRef.Namespace, Name: endpointAddress.TargetRef.Name}
				}
			}
		}
	}
	if !foundMatchingPort {
		klog.Errorf("Service port name %q was not found in the endpoints object %+v", servicePortName, eds)
	}

	if len(zoneNetworkEndpointMap) == 0 || len(networkEndpointPodMap) == 0 {
		klog.V(3).Infof("Generated empty endpoint maps (zoneNetworkEndpointMap: %+v, networkEndpointPodMap: %v) from Endpoints object: %+v", zoneNetworkEndpointMap, networkEndpointPodMap, eds)
	}
	return zoneNetworkEndpointMap, networkEndpointPodMap, nil
}