package controller import ( "context" "errors" "fmt" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" ) // Destination is a resolved backup target parsed from the operator's // destinations ConfigMap. type Destination struct { PlacementTarget string `json:"placementTarget,omitempty"` Zonegroup string `json:"zonegroup,omitempty"` Endpoint string `json:"endpoint,omitempty"` EndpointCASecret string `json:"endpointCASecret,omitempty"` EndpointCAKey string `json:"endpointCAKey,omitempty"` } // errDestinationNotFound signals a missing ConfigMap or entry so callers can // emit a Warning event and requeue instead of treating it as a hard failure. var errDestinationNotFound = errors.New("destination not found") // resolveDestination looks a logical destination name up in the operator's // destinations ConfigMap and parses its YAML entry. func resolveDestination(ctx context.Context, c client.Client, ns, cmName, dest string) (Destination, error) { var cm corev1.ConfigMap if err := c.Get(ctx, types.NamespacedName{Namespace: ns, Name: cmName}, &cm); err != nil { if apierrors.IsNotFound(err) { return Destination{}, fmt.Errorf("destinations ConfigMap %s/%s: %w", ns, cmName, errDestinationNotFound) } return Destination{}, err } raw, ok := cm.Data[dest] if !ok { return Destination{}, fmt.Errorf("destination %q: %w", dest, errDestinationNotFound) } var d Destination if err := yaml.Unmarshal([]byte(raw), &d); err != nil { return Destination{}, fmt.Errorf("destination %q: %w", dest, err) } if d.Endpoint == "" { return Destination{}, fmt.Errorf("destination %q: missing endpoint", dest) } return d, nil }