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
}