func()

in pkg/controllers/serviceexport_controller.go [95:165]


func (r *ServiceExportReconciler) handleUpdate(ctx context.Context, serviceExport *v1alpha1.ServiceExport, service *v1.Service) (ctrl.Result, error) {
	// Add the finalizer to the service export if not present, ensures the ServiceExport won't be deleted
	if !controllerutil.ContainsFinalizer(serviceExport, ServiceExportFinalizer) {
		controllerutil.AddFinalizer(serviceExport, ServiceExportFinalizer)
		if err := r.Client.Update(ctx, serviceExport); err != nil {
			r.Log.Error(err, "error adding finalizer",
				"Namespace", serviceExport.Namespace, "Name", serviceExport.Name)
			return ctrl.Result{}, err
		}
	}

	if len(serviceExport.GetOwnerReferences()) == 0 {
		err := controllerutil.SetControllerReference(service, serviceExport, r.Scheme)
		if err == nil {
			err = r.Client.Update(ctx, serviceExport)
		}
		if err != nil {
			r.Log.Error(err, "error setting Service as an owner of the ServiceExport",
				"namespace", service.Namespace, "name", service.Name)
			return ctrl.Result{}, err
		}
	}

	r.Log.Info("updating Cloud Map service", "namespace", service.Namespace, "name", service.Name)
	cmService, err := r.createOrGetCloudMapService(ctx, service)
	if err != nil {
		r.Log.Error(err, "error fetching Service from Cloud Map",
			"namespace", service.Namespace, "name", service.Name)
		return ctrl.Result{}, err
	}

	endpoints, err := r.extractEndpoints(ctx, service)
	if err != nil {
		r.Log.Error(err, "error extracting Endpoints",
			"namespace", serviceExport.Namespace, "name", serviceExport.Name)
		return ctrl.Result{}, err
	}

	// Compute diff between Cloud Map and K8s endpoints, and apply changes
	plan := model.Plan{
		Current: cmService.Endpoints,
		Desired: endpoints,
	}
	changes := plan.CalculateChanges()

	if changes.HasUpdates() {
		// merge creates and updates (Cloud Map RegisterEndpoints can handle both)
		upserts := changes.Create
		upserts = append(upserts, changes.Update...)

		if err := r.CloudMap.RegisterEndpoints(ctx, service.Namespace, service.Name, upserts); err != nil {
			r.Log.Error(err, "error registering Endpoints to Cloud Map",
				"namespace", service.Namespace, "name", service.Name)
			return ctrl.Result{}, err
		}
	}

	if changes.HasDeletes() {
		if err := r.CloudMap.DeleteEndpoints(ctx, service.Namespace, service.Name, changes.Delete); err != nil {
			r.Log.Error(err, "error deleting Endpoints from Cloud Map",
				"namespace", cmService.Namespace, "name", cmService.Name)
			return ctrl.Result{}, err
		}
	}

	if changes.IsNone() {
		r.Log.Info("no changes to export to Cloud Map", "namespace", service.Namespace, "name", service.Name)
	}

	return ctrl.Result{}, nil
}