func()

in controllers/service_controller.go [69:206]


func (r *ServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	logger := log.FromContext(ctx).WithValues("service", req.NamespacedName)

	svc := &corev1.Service{}
	err := r.Get(ctx, req.NamespacedName, svc)
	if err != nil {
		if apierrors.IsNotFound(err) {
			// Object not found, return.
			return r.reconcileResult(nil)
		}
		// Error reading the object - requeue the request.
		return r.reconcileResult(err)
	}

	status, ok, err := getStatuses(svc.Namespace, svc.Name, svc.ObjectMeta.Annotations, r)
	// Is this service using autoneg?
	if !ok {
		return r.reconcileResult(nil)
	}

	if err != nil {
		r.Recorder.Event(svc, "Warning", "ConfigError", err.Error())
		return r.reconcileResult(err)
	}

	deleting := false
	// Process deletion
	if !svc.ObjectMeta.DeletionTimestamp.IsZero() && (containsString(svc.ObjectMeta.Finalizers, oldAutonegFinalizer) || containsString(svc.ObjectMeta.Finalizers, autonegFinalizer)) {
		logger.Info("Deleting service")
		deleting = true
	}

	intendedStatus := AutonegStatus{
		AutonegConfig: status.config,
		NEGStatus:     status.negStatus,
	}
	logger.Info("Existing status", "status", status)
	if status.syncConfig != nil {
		intendedStatus.AutonegSyncConfig = status.syncConfig
	}

	oldIntendedStatus := OldAutonegStatus{
		OldAutonegConfig: status.oldConfig,
		NEGStatus:        status.negStatus,
	}

	if deleting {
		intendedStatus.BackendServices = make(map[string]map[string]AutonegNEGConfig, 0)
	} else if reflect.DeepEqual(status.status, intendedStatus) && !r.AlwaysReconcile {
		// Equal, no reconciliation necessary
		return r.reconcileResult(nil)
	}

	// Reconcile differences
	logger.Info("Applying intended status", "status", intendedStatus)

	if err = r.ReconcileBackends(status.status, intendedStatus); err != nil {
		var e *errNotFound
		if !(deleting && errors.As(err, &e)) {
			r.Recorder.Event(svc, "Warning", "BackendError", err.Error())
			return r.reconcileResult(err)
		}
		if deleting {
			r.Recorder.Event(svc, "Warning", "BackendError while deleting", err.Error())
			return r.reconcileResult(err)
		}
	}

	// Write changes to the service object.
	if deleting {
		// Remove finalizer and clear status
		svc.ObjectMeta.Finalizers = removeString(svc.ObjectMeta.Finalizers, oldAutonegFinalizer)
		svc.ObjectMeta.Finalizers = removeString(svc.ObjectMeta.Finalizers, autonegFinalizer)
		delete(svc.ObjectMeta.Annotations, autonegStatusAnnotation)
		delete(svc.ObjectMeta.Annotations, oldAutonegStatusAnnotation)
	} else {
		// Remove old finalizer
		if containsString(svc.ObjectMeta.Finalizers, oldAutonegFinalizer) {
			logger.Info("Upgrading finalizer")
			svc.ObjectMeta.Finalizers = removeString(svc.ObjectMeta.Finalizers, oldAutonegFinalizer)
			svc.ObjectMeta.Finalizers = append(svc.ObjectMeta.Finalizers, autonegFinalizer)
		} else {
			// Add the finalizer annotation if it doesn't exist.
			if !containsString(svc.ObjectMeta.Finalizers, autonegFinalizer) {
				logger.Info("Adding finalizer")
				svc.ObjectMeta.Finalizers = append(svc.ObjectMeta.Finalizers, autonegFinalizer)
			}
		}

		// Write status to annotations
		anStatus, err := json.Marshal(intendedStatus)
		if err != nil {
			logger.Error(err, "json marshal error")
			return r.reconcileResult(err)
		}
		svc.ObjectMeta.Annotations[autonegStatusAnnotation] = string(anStatus)

		if !status.newConfig {
			oldStatus, err := json.Marshal(oldIntendedStatus)

			if err != nil {
				logger.Error(err, "json marshal error")
				return r.reconcileResult(err)
			}

			svc.ObjectMeta.Annotations[oldAutonegStatusAnnotation] = string(oldStatus)
		}
	}

	if err = r.Update(ctx, svc); err != nil {
		// Do not record an event in case of routine object conflict.
		if !apierrors.IsConflict(err) {
			r.Recorder.Event(svc, "Warning", "BackendError", err.Error())
		}
		return r.reconcileResult(err)
	}

	for port, endpointGroups := range intendedStatus.BackendServices {
		for _, endpointGroup := range endpointGroups {
			if deleting {
				r.Recorder.Eventf(svc, "Normal", "Delete",
					"Deregistered NEGs for %q from backend service %q (port %s)",
					req.NamespacedName,
					endpointGroup.Name,
					port)

			} else {
				r.Recorder.Eventf(svc, "Normal", "Sync",
					"Synced NEGs for %q as backends to backend service %q (port %s)",
					req.NamespacedName,
					endpointGroup.Name,
					port)
			}
		}
	}

	return r.reconcileResult(nil)
}