in internal/controllers/reconciliation/controller.go [92:160]
func (c *Controller) Reconcile(ctx context.Context, req resource.Request) (ctrl.Result, error) {
logger := logr.FromContextOrDiscard(ctx)
comp := &apiv1.Composition{}
err := c.client.Get(ctx, types.NamespacedName{Name: req.Composition.Name, Namespace: req.Composition.Namespace}, comp)
if err != nil {
logger.Error(err, "failed to get composition")
return ctrl.Result{}, client.IgnoreNotFound(err)
}
synthesisUUID := comp.Status.GetCurrentSynthesisUUID()
logger = logger.WithValues("compositionName", comp.Name, "compositionNamespace", comp.Namespace, "compositionGeneration", comp.Generation, "synthesisUUID", synthesisUUID)
if comp.Status.CurrentSynthesis == nil {
return ctrl.Result{}, nil // nothing to do
}
logger = logger.WithValues("synthesizerName", comp.Spec.Synthesizer.Name, "synthesizerGeneration", comp.Status.CurrentSynthesis.ObservedSynthesizerGeneration, "synthesisUUID", comp.Status.GetCurrentSynthesisUUID())
ctx = logr.NewContext(ctx, logger)
// Find the current and (optionally) previous desired states in the cache
var prev *resource.Resource
resource, visible, exists := c.resourceClient.Get(ctx, synthesisUUID, req.Resource)
if !exists || !visible {
return ctrl.Result{}, nil
}
logger = logger.WithValues("resourceKind", resource.Ref.Kind, "resourceName", resource.Ref.Name, "resourceNamespace", resource.Ref.Namespace)
ctx = logr.NewContext(ctx, logger)
if syn := comp.Status.PreviousSynthesis; syn != nil {
prev, _, _ = c.resourceClient.Get(ctx, syn.UUID, req.Resource)
}
// Fetch the current resource
current, err := c.getCurrent(ctx, resource)
if client.IgnoreNotFound(err) != nil && !isErrMissingNS(err) && !isErrNoKindMatch(err) {
logger.Error(err, "failed to get current state")
return ctrl.Result{}, err
}
// Evaluate resource readiness
// - Readiness checks are skipped when this version of the resource's desired state has already become ready
// - Readiness checks are skipped when the resource hasn't changed since the last check
// - Readiness defaults to true if no checks are given
var ready *metav1.Time
status := resource.State()
if status == nil || status.Ready == nil {
readiness, ok := resource.ReadinessChecks.EvalOptionally(ctx, current)
if ok {
ready = &readiness.ReadyTime
}
} else {
ready = status.Ready
}
modified, err := c.reconcileResource(ctx, comp, prev, resource, current)
if err != nil {
logger.Error(err, "failed to reconcile resource")
return ctrl.Result{}, err
}
if modified {
return ctrl.Result{Requeue: true}, nil
}
deleted := current == nil ||
current.GetDeletionTimestamp() != nil ||
(resource.Deleted(comp) && comp.ShouldOrphanResources()) // orphaning should be reflected on the status.
c.writeBuffer.PatchStatusAsync(ctx, &resource.ManifestRef, patchResourceState(deleted, ready))
return c.requeue(logger, comp, resource, ready)
}