in pkg/controller/nginxingress/nginx_ingress_controller.go [95:184]
func (n *nginxIngressControllerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, err error) {
start := time.Now()
lgr := log.FromContext(ctx, "nginxIngressController", req.NamespacedName)
ctx = log.IntoContext(ctx, lgr)
lgr.Info("reconciling NginxIngressController")
defer lgr.Info("finished reconciling resource", "latencySec", time.Since(start).String())
defer func() {
metrics.HandleControllerReconcileMetrics(nginxIngressControllerReconcilerName, res, err)
}()
var nginxIngressController approutingv1alpha1.NginxIngressController
if err := n.client.Get(ctx, req.NamespacedName, &nginxIngressController); err != nil {
if apierrors.IsNotFound(err) { // object was deleted
lgr.Info("NginxIngressController not found")
return ctrl.Result{}, nil
}
lgr.Error(err, "unable to fetch NginxIngressController")
return ctrl.Result{}, err
}
lgr = lgr.WithValues("generation", nginxIngressController.Generation)
ctx = log.IntoContext(ctx, lgr)
var managedRes []approutingv1alpha1.ManagedObjectReference = nil
var controllerDeployment *appsv1.Deployment = nil
var ingressClass *netv1.IngressClass = nil
lockKey := nginxIngressController.Spec.ControllerNamePrefix
collisionCountMu.LockKey(lockKey)
defer collisionCountMu.UnlockKey(lockKey)
lgr.Info("determining collision count")
startingCollisionCount := nginxIngressController.Status.CollisionCount
newCollisionCount, collisionCountErr := n.GetCollisionCount(ctx, &nginxIngressController)
if collisionCountErr == nil && newCollisionCount != startingCollisionCount {
nginxIngressController.Status.CollisionCount = newCollisionCount
if err := n.client.Status().Update(ctx, &nginxIngressController); err != nil {
lgr.Error(err, "unable to update collision count status")
return ctrl.Result{}, fmt.Errorf("updating status: %w", err)
}
return ctrl.Result{Requeue: true}, nil
}
defer func() { // defer is before checking err so that we can update status even if there is an error
lgr.Info("updating status")
n.updateStatus(&nginxIngressController, controllerDeployment, ingressClass, managedRes, collisionCountErr)
if statusErr := n.client.Status().Update(ctx, &nginxIngressController); statusErr != nil {
if apierrors.IsConflict(statusErr) {
lgr.Info("conflict updating status, requeuing")
res = ctrl.Result{Requeue: true}
err = nil
return
}
if err == nil {
lgr.Error(statusErr, "unable to update NginxIngressController status")
err = statusErr
}
}
}()
if collisionCountErr != nil {
if isUnreconcilableError(collisionCountErr) {
lgr.Info("unreconcilable collision count")
return ctrl.Result{RequeueAfter: time.Minute}, nil // requeue in case cx fixes the unreconcilable reason
}
lgr.Error(collisionCountErr, "unable to get determine collision count")
return ctrl.Result{}, fmt.Errorf("determining collision count: %w", collisionCountErr)
}
lgr.Info("calculating managed resources")
resources := n.ManagedResources(&nginxIngressController)
if resources == nil {
return ctrl.Result{}, fmt.Errorf("unable to get managed resources")
}
controllerDeployment = resources.Deployment
ingressClass = resources.IngressClass
lgr.Info("reconciling managed resources")
managedRes, err = n.ReconcileResource(ctx, &nginxIngressController, resources)
if err != nil {
lgr.Error(err, "unable to reconcile resource")
return ctrl.Result{}, fmt.Errorf("reconciling resource: %w", err)
}
if replicas := resources.Deployment.Spec.Replicas; replicas != nil {
lgr.Info(fmt.Sprintf("nginx deployment targets %d replicas", *replicas), "replicas", *replicas)
}
return ctrl.Result{}, nil
}