in internal/controllers/symphony/controller.go [156:218]
func (c *symphonyController) reconcileForward(ctx context.Context, symph *apiv1.Symphony, comps *apiv1.CompositionList) (modified bool, err error) {
logger := logr.FromContextOrDiscard(ctx)
for _, variation := range symph.Spec.Variations {
variation := variation
comp := &apiv1.Composition{}
comp.Namespace = symph.Namespace
comp.GenerateName = variation.Synthesizer.Name + "-"
comp.Spec.Bindings = getBindings(symph, &variation)
comp.Spec.Synthesizer = variation.Synthesizer
comp.Spec.SynthesisEnv = getSynthesisEnv(symph, &variation)
comp.Labels = variation.Labels
comp.Annotations = variation.Annotations
err := controllerutil.SetControllerReference(symph, comp, c.client.Scheme())
if err != nil {
return false, fmt.Errorf("setting composition's controller: %w", err)
}
logger := logger.WithValues("compositionName", comp.Name, "compositionNamespace", comp.Namespace)
// Compose missing variations
idx := slices.IndexFunc(comps.Items, func(existing apiv1.Composition) bool {
return existing.Spec.Synthesizer.Name == variation.Synthesizer.Name
})
if idx == -1 {
err := c.noCacheClient.List(ctx, comps, client.InNamespace(symph.Namespace))
if err != nil {
return false, fmt.Errorf("listing existing compositions without cache: %w", err)
}
for _, cur := range comps.Items {
owner := metav1.GetControllerOf(&cur)
if owner != nil && owner.UID == symph.UID && cur.Spec.Synthesizer.Name == variation.Synthesizer.Name {
return false, fmt.Errorf("stale cache - composition already exists")
}
}
err = c.client.Create(ctx, comp)
if k8serrors.IsForbidden(err) && k8serrors.HasStatusCause(err, corev1.NamespaceTerminatingCause) {
logger.V(0).Info("skipping composition creation because the namespace is being terminated")
return false, nil
}
if err != nil {
return false, fmt.Errorf("creating composition: %w", err)
}
logger.V(0).Info("created composition for symphony")
return true, nil
}
// Diff and update if needed
existing := comps.Items[idx]
if equality.Semantic.DeepEqual(comp.Spec, existing.Spec) && !coalesceMetadata(&variation, &existing) {
continue // already matches
}
existing.Spec = comp.Spec
err = c.client.Update(ctx, &existing)
if err != nil {
return false, fmt.Errorf("updating existing composition: %w", err)
}
logger.V(0).Info("updated composition because its variation changed")
return true, nil
}
return false, nil
}