func()

in pkg/controllers/hub/internalserviceexport/controller.go [190:247]


func (r *Reconciler) handleUpdate(ctx context.Context, internalServiceExport *fleetnetv1alpha1.InternalServiceExport) (ctrl.Result, error) {
	internalServiceExportKObj := klog.KObj(internalServiceExport)
	// get serviceImport
	serviceImport := &fleetnetv1alpha1.ServiceImport{}
	serviceImportName := types.NamespacedName{Namespace: internalServiceExport.Spec.ServiceReference.Namespace, Name: internalServiceExport.Spec.ServiceReference.Name}
	serviceImportKRef := klog.KRef(serviceImportName.Namespace, serviceImportName.Name)

	if err := r.Client.Get(ctx, serviceImportName, serviceImport); err != nil {
		if !errors.IsNotFound(err) {
			klog.ErrorS(err, "Failed to get serviceImport", "serviceImport", serviceImportKRef, "internalServiceExport", internalServiceExportKObj)
			return ctrl.Result{}, err
		}
		serviceImport = &fleetnetv1alpha1.ServiceImport{
			ObjectMeta: metav1.ObjectMeta{
				Namespace: serviceImportName.Namespace,
				Name:      serviceImportName.Name,
			},
		}
		klog.V(2).InfoS("Creating serviceImport", "serviceImport", serviceImportKRef, "internalServiceExport", internalServiceExportKObj)
		if err := r.Client.Create(ctx, serviceImport); err != nil {
			klog.ErrorS(err, "Failed to create or update service import", "serviceImport", serviceImportKRef, "internalServiceExport", internalServiceExportKObj)
			return ctrl.Result{}, err
		}
	}

	if len(serviceImport.Status.Ports) == 0 {
		// Requeue the request and waiting for the ServiceImport controller to resolve the spec.
		klog.V(3).InfoS("Waiting for serviceImport controller to resolve the spec", "serviceImport", serviceImportKRef, "internalServiceExport", internalServiceExportKObj)
		return ctrl.Result{RequeueAfter: r.RetryInternal}, nil
	}

	oldStatus := serviceImport.Status.DeepCopy()
	clusterID := internalServiceExport.Spec.ServiceReference.ClusterID

	// To simplify the implementation, we compare the whole ports structure.
	// TODO, change to compare the ports by ignoring the order and protocol and port are the map keys.
	if !equality.Semantic.DeepEqual(serviceImport.Status.Ports, internalServiceExport.Spec.Ports) {
		removeClusterFromServiceImportStatus(serviceImport, clusterID)
		if err := r.updateServiceImportStatus(ctx, serviceImport, oldStatus); err != nil {
			return ctrl.Result{}, err
		}
		// It's possible, eg, there is only one serviceExport and its spec has been changed.
		// ServiceImport stores the old spec of this ServiceExport and later the serviceExport changes its spec.
		if len(serviceImport.Status.Ports) == 0 {
			klog.V(3).InfoS("Removed the cluster and waiting for serviceImport controller to resolve the spec", "serviceImport", serviceImportKRef, "internalServiceExport", internalServiceExportKObj)
			// Requeue the request and waiting for the ServiceImport controller to resolve the spec.
			return ctrl.Result{RequeueAfter: r.RetryInternal}, nil
		}
		return ctrl.Result{}, r.updateInternalServiceExportStatus(ctx, internalServiceExport, true)
	}

	addClusterToServiceImportStatus(serviceImport, clusterID)
	if err := r.updateServiceImportStatus(ctx, serviceImport, oldStatus); err != nil {
		return ctrl.Result{}, err
	}

	return ctrl.Result{}, r.updateInternalServiceExportStatus(ctx, internalServiceExport, false)
}