in controllers/core/pod_controller.go [64:165]
func (r *PodReconciler) Reconcile(request custom.Request) (ctrl.Result, error) {
var isDeleteEvent bool
var hasPodCompleted bool
var pod *v1.Pod
if request.DeletedObject != nil {
isDeleteEvent = true
pod = request.DeletedObject.(*v1.Pod)
} else {
obj, exists, err := r.DataStore.GetByKey(request.NamespacedName.String())
if err != nil {
r.Log.Error(err, "failed to retrieve the pod object",
"namespace name", request.NamespacedName.String())
return ctrl.Result{}, nil
}
if !exists {
r.Log.V(1).Info("pod doesn't exists in the cache anymore",
"namespace name", request.NamespacedName.String())
return ctrl.Result{}, nil
}
// convert to pod object
pod = obj.(*v1.Pod)
}
// If Pod is Completed, the networking for the Pod should be removed
// given the container will not be restarted again
hasPodCompleted = pod.Status.Phase == v1.PodSucceeded ||
pod.Status.Phase == v1.PodFailed
logger := r.Log.WithValues("UID", pod.UID, "pod", request.NamespacedName,
"node", pod.Spec.NodeName)
// If the Pod doesn't have a Node assigned, ignore the request instead of querying the
// node manager
if pod.Spec.NodeName == "" {
return ctrl.Result{}, nil
}
// On Controller startup, the Pod event should be processed after the Pod's node
// has initialized (or it will be stuck till the next re-sync period or Pod update).
// Once the Pod has been initialized if it's managed then wait till the asynchronous
// operation on the Node has been performed and node is ready to server requests.
node, foundInCache := r.NodeManager.GetNode(pod.Spec.NodeName)
nodeDeletedInCluster := false
if !isDeleteEvent && r.isNodeExistingInCluster(pod, logger) {
if !foundInCache {
logger.V(1).Info("pod's node is not yet initialized by the manager, will retry", "Requested", request.NamespacedName.String(), "Cached pod name", pod.ObjectMeta.Name, "Cached pod namespace", pod.ObjectMeta.Namespace)
return PodRequeueRequest, nil
} else if !node.IsManaged() {
if utils.PodHasENIRequest(pod) {
r.Log.Info("pod's node is not managed, but has eni request, will retry", "Requested", request.NamespacedName.String(), "Cached pod name", pod.ObjectMeta.Name, "Cached pod namespace", pod.ObjectMeta.Namespace)
return PodRequeueRequest, nil
}
logger.V(1).Info("pod's node is not managed, skipping pod event", "Requested", request.NamespacedName.String(), "Cached pod name", pod.ObjectMeta.Name, "Cached pod namespace", pod.ObjectMeta.Namespace)
return ctrl.Result{}, nil
} else if !node.IsReady() {
logger.V(1).Info("pod's node is not ready to handle request yet, will retry", "Requested", request.NamespacedName.String(), "Cached pod name", pod.ObjectMeta.Name, "Cached pod namespace", pod.ObjectMeta.Namespace)
return PodRequeueRequest, nil
}
} else if foundInCache && !node.IsManaged() {
return ctrl.Result{}, nil
} else if !isDeleteEvent {
nodeDeletedInCluster = true
}
// Get the aggregate level resource, vpc controller doesn't support allocating
// container level resources
aggregateResources := getAggregateResources(pod)
logger.V(1).Info("Pod controller logs local variables", "isDeleteEvent", isDeleteEvent, "hasPodCompleted", hasPodCompleted, "nodeDeletedInCluster", nodeDeletedInCluster)
// For each resource, if a handler can allocate/de-allocate a resource then delegate the
// allocation/de-allocation task to the respective handler
for resourceName, totalCount := range aggregateResources {
// Pod annotation ResourceNameIPAddress has two resource managers: secondary IP and prefix IP;
// backend needs to distinguish which resource provider and handler should be used here accordingly
if resourceName == config.ResourceNameIPAddress {
resourceName = r.updateResourceName(isDeleteEvent || hasPodCompleted || nodeDeletedInCluster, pod, node)
}
resourceHandler, isSupported := r.ResourceManager.GetResourceHandler(resourceName)
if !isSupported {
continue
}
var err error
var result ctrl.Result
if isDeleteEvent || hasPodCompleted || nodeDeletedInCluster {
result, err = resourceHandler.HandleDelete(pod)
} else {
result, err = resourceHandler.HandleCreate(int(totalCount), pod)
}
if err != nil || result.Requeue {
return result, err
}
logger.V(1).Info("handled resource without error",
"resource", resourceName, "is delete event", isDeleteEvent,
"has pod completed", hasPodCompleted)
}
return ctrl.Result{}, nil
}