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)
}