func()

in pkg/controllers/member/internalserviceexport/controller.go [83:159]


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

	// Retrieve the InternalServiceExport object.
	var internalSvcExport fleetnetv1alpha1.InternalServiceExport
	if err := r.HubClient.Get(ctx, req.NamespacedName, &internalSvcExport); err != nil {
		// Skip the reconciliation if the InternalServiceExport does not exist.
		if errors.IsNotFound(err) {
			klog.V(4).InfoS("Ignoring NotFound internalServiceExport", "internalServiceExport", internalSvcExportRef)
			return ctrl.Result{}, nil
		}
		klog.ErrorS(err, "Failed to get internal svc export", "internalServiceExport", internalSvcExportRef)
		return ctrl.Result{}, err
	}

	if !internalSvcExport.ObjectMeta.DeletionTimestamp.IsZero() {
		// Skip the reconciliation if the InternalServiceExport is being deleted.
		// There is no need to report the conflicts back.
		// For example, the serviceExport is no longer valid or valid with 0 weight.
		// In these cases, there is no need to create internalServiceExport.
		klog.V(2).InfoS("Ignoring deleting internalServiceExport", "internalServiceExport", internalSvcExportRef)
		return ctrl.Result{}, nil
	}

	// Check if the exported Service exists.
	svcNS := internalSvcExport.Spec.ServiceReference.Namespace
	svcName := internalSvcExport.Spec.ServiceReference.Name
	svcExportRef := klog.KRef(svcNS, svcName)
	var svcExport fleetnetv1alpha1.ServiceExport
	err := r.MemberClient.Get(ctx, types.NamespacedName{Namespace: svcNS, Name: svcName}, &svcExport)
	switch {
	case errors.IsNotFound(err):
		// The absence of ServiceExport suggests that the Service should not be, yet has been, exported. Normally
		// this situation will never happen as the ServiceExport controller guarantees, using the cleanup finalizer,
		// that a ServiceExport will only be deleted after the Service has been unexported. In some corner cases,
		// however, e.g. the user chooses to remove the finalizer explicitly, a Service can be left over in the hub
		// cluster, and it is up to this controller to remove it.
		klog.V(2).InfoS("Svc export does not exist; delete the internal svc export",
			"serviceExport", svcExportRef,
			"internalServiceExport", internalSvcExportRef,
		)
		if err := r.HubClient.Delete(ctx, &internalSvcExport); err != nil {
			klog.ErrorS(err, "Failed to delete internal svc export", "internalServiceExport", internalSvcExportRef)
			return ctrl.Result{}, err
		}
		return ctrl.Result{}, nil
	case err != nil:
		// An unexpected error occurs.
		klog.ErrorS(err, "Failed to get svc export", "serviceExport", svcExportRef)
		return ctrl.Result{}, err
	}

	// Report back conflict resolution result.
	klog.V(4).InfoS("Report back conflict resolution result", "internalServiceExport", internalSvcExportRef)
	reported, err := r.reportBackConflictCondition(ctx, &svcExport, &internalSvcExport)
	if err != nil {
		klog.ErrorS(err, "Failed to report back conflict resolution result", "serviceExport", svcExportRef)
		return ctrl.Result{}, err
	}

	// Observe a data point for the svcExportDuration metric.
	// Note that an observation happens only when there is a conflict resolution result to report back.
	if reported {
		if err := r.observeMetrics(ctx, &internalSvcExport, time.Now()); err != nil {
			klog.ErrorS(err, "Failed to observe metrics", "internalServiceExport", internalSvcExportRef)
			return ctrl.Result{}, err
		}
	}

	return ctrl.Result{}, nil
}