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
}