in pkg/controller/association/reconciler.go [146:226]
func (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
nameField := fmt.Sprintf("%s_name", r.AssociatedShortName)
ctx = common.NewReconciliationContext(ctx, &r.iteration, r.Tracer, r.AssociationName, nameField, request)
defer common.LogReconciliationRun(ulog.FromContext(ctx))()
defer tracing.EndContextTransaction(ctx)
log := ulog.FromContext(ctx)
associated := r.AssociatedObjTemplate()
if err := r.Client.Get(ctx, request.NamespacedName, associated); err != nil {
if apierrors.IsNotFound(err) {
// object resource has been deleted, remove artifacts related to the association.
r.onDelete(ctx, types.NamespacedName{
Namespace: request.Namespace,
Name: request.Name,
})
return reconcile.Result{}, nil
}
return reconcile.Result{}, tracing.CaptureError(ctx, err)
}
associatedKey := k8s.ExtractNamespacedName(associated)
if common.IsUnmanaged(ctx, associated) {
log.Info("Object is currently not managed by this controller. Skipping reconciliation")
return reconcile.Result{}, nil
}
if !associated.GetDeletionTimestamp().IsZero() {
// Object is being deleted, short-circuit reconciliation
return reconcile.Result{}, nil
}
if err := RemoveObsoleteAssociationConfs(ctx, r.Client, associated, r.AssociationConfAnnotationNameBase); err != nil {
return reconcile.Result{}, tracing.CaptureError(ctx, err)
}
// we are only interested in associations of the same target type here
// (e.g. Kibana -> Enterprise Search, not Kibana -> Elasticsearch)
associations := make([]commonv1.Association, 0)
for _, association := range associated.GetAssociations() {
if association.AssociationType() == r.AssociationType {
associations = append(associations, association)
}
}
// garbage collect leftover resources that are not required anymore
if err := deleteOrphanedResources(ctx, r.Client, r.AssociationInfo, associatedKey, associations); err != nil {
log.Error(err, "Error while trying to delete orphaned resources. Continuing.")
}
// reconcile watches for all associations of this type
if err := r.reconcileWatches(ctx, associatedKey, associations); err != nil {
return reconcile.Result{}, tracing.CaptureError(ctx, err)
}
results := reconciler.NewResult(ctx)
newStatusMap := commonv1.AssociationStatusMap{}
for _, association := range associations {
newStatus, err := r.reconcileAssociation(ctx, association)
if err != nil {
results.WithError(err)
}
newStatusMap[association.AssociationRef().NamespacedName().String()] = newStatus
}
// we want to attempt a status update even in the presence of errors
if err := r.updateStatus(ctx, associated, newStatusMap); err != nil && apierrors.IsConflict(err) {
log.V(1).Info(
"Conflict while updating status",
"namespace", associatedKey.Namespace,
"name", associatedKey.Name)
return results.WithResult(reconcile.Result{Requeue: true}).Aggregate()
} else if err != nil {
return defaultRequeue, tracing.CaptureError(ctx, errors.Wrapf(err, "while updating status"))
}
return results.
WithResult(RequeueRbacCheck(r.accessReviewer)).
WithResult(resultFromStatuses(newStatusMap)).
Aggregate()
}