func()

in pkg/controllers/member/endpointsliceexport/controller.go [39:99]


func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	endpointSliceExportRef := klog.KRef(req.Namespace, req.Name)
	startTime := time.Now()
	klog.V(2).InfoS("Reconciliation starts", "endpointSliceExport", endpointSliceExportRef)
	defer func() {
		latency := time.Since(startTime).Seconds()
		klog.V(2).InfoS("Reconciliation ends", "endpointSliceExport", endpointSliceExportRef, "latency", latency)
	}()

	// Retrieve the EndpointSliceExport object.
	endpointSliceExport := &fleetnetv1alpha1.EndpointSliceExport{}
	if err := r.HubClient.Get(ctx, req.NamespacedName, endpointSliceExport); err != nil {
		// Skip the reconciliation if the EndpointSliceExport does not exist; this should only happen when an
		// EndpointSliceExport is deleted before the controller gets a chance to reconcile it;
		// this requires no action to take on this controller's end.
		if errors.IsNotFound(err) {
			klog.V(4).InfoS("Ignoring NotFound endpointSliceExport", "endpointSliceExport", endpointSliceExportRef)
			return ctrl.Result{}, nil
		}
		klog.ErrorS(err, "Failed to get endpointSliceExport", "endpointSliceExport", endpointSliceExportRef)
		return ctrl.Result{}, err
	}

	// Check if the EndpointSliceExport refers to an existing EndpointSlice.
	endpointSlice := &discoveryv1.EndpointSlice{}
	endpointSliceKey := types.NamespacedName{
		Namespace: endpointSliceExport.Spec.EndpointSliceReference.Namespace,
		Name:      endpointSliceExport.Spec.EndpointSliceReference.Name,
	}
	endpointSliceRef := klog.KRef(endpointSliceKey.Namespace, endpointSliceKey.Name)
	err := r.MemberClient.Get(ctx, endpointSliceKey, endpointSlice)
	switch {
	case errors.IsNotFound(err):
		// The matching EndpointSlice is not found; the EndpointSliceExport should be deleted.
		klog.V(2).InfoS("Referred endpointSlice is not found; delete the endpointSliceExport",
			"endpointSliceExport", endpointSliceExportRef,
			"endpointSlice", endpointSliceRef,
		)
		return r.deleteEndpointSliceExport(ctx, endpointSliceExport)
	case err != nil:
		// An unexpected error has occurred.
		klog.ErrorS(err, "Failed to get endpointSlice",
			"endpointSliceExport", endpointSliceExportRef,
			"endpointSlice", endpointSliceRef)
		return ctrl.Result{}, err
	}

	// Check if the EndpointSliceExport is linked the referred EndpointSlice by the assigned unique name for export.
	// This helps guard against some corner cases, e.g.
	// * A user tampers with the unique name for export assigned to an EndpointSlice,
	//   which leads to the same EndpointSlice being exported for multiple times with different names.
	// * An EndpointSlice is deleted and immediately re-created with the same name, and the EndpointSlice
	//   controller fails to unexport the EndpointSlice in time when it is deleted.
	if !isEndpointSliceExportLinkedWithEndpointSlice(endpointSliceExport, endpointSlice) {
		return r.deleteEndpointSliceExport(ctx, endpointSliceExport)
	}

	// Periodically re-scan EndpointSliceExports; this help addresses corner cases where an EndpointSlice
	// is deleted without the EndpointSlice controller getting a chance to withdraw it from the hub cluster.
	return ctrl.Result{RequeueAfter: endpointSliceExportRetryInterval}, nil
}