From cfbd86b2e106ac140154a6869f8208e2aa14fa74 Mon Sep 17 00:00:00 2001 From: Bence Csati Date: Tue, 12 Nov 2024 11:03:52 +0100 Subject: [PATCH] fix: report correct tenant state on bridge failure Signed-off-by: Bence Csati --- .../telemetry/collector_controller.go | 7 +++- .../controller/telemetry/route_controller.go | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/internal/controller/telemetry/collector_controller.go b/internal/controller/telemetry/collector_controller.go index 59be58b..77c8200 100644 --- a/internal/controller/telemetry/collector_controller.go +++ b/internal/controller/telemetry/collector_controller.go @@ -80,7 +80,7 @@ func (r *CollectorReconciler) buildConfigInputForCollector(ctx context.Context, for _, tenant := range tenants { if tenant.Status.State == v1alpha1.StateFailed { - logger.Info("tenant %q is in failed state, retrying later", tenant.Name) + logger.Info(fmt.Sprintf("tenant %q is in failed state, retrying later", tenant.Name)) return otelcolconfgen.OtelColConfigInput{}, ErrTenantFailed } @@ -196,6 +196,11 @@ func (r *CollectorReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( } if err := otelConfigInput.ValidateConfig(); err != nil { + if errors.Is(err, otelcolconfgen.ErrNoResources) { + logger.Info(err.Error()) + return ctrl.Result{}, nil + } + collector.Status.State = v1alpha1.StateFailed logger.Error(errors.WithStack(err), "invalid otel config input") return ctrl.Result{}, err diff --git a/internal/controller/telemetry/route_controller.go b/internal/controller/telemetry/route_controller.go index a9037fe..3310887 100644 --- a/internal/controller/telemetry/route_controller.go +++ b/internal/controller/telemetry/route_controller.go @@ -138,6 +138,18 @@ func (r *RouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl sort.Strings(bridgesForTenantNames) tenant.Status.ConnectedBridges = bridgesForTenantNames + for _, bridge := range bridgesForTenant { + if err := r.checkBridgeConnection(ctx, tenant.Name, &bridge); err != nil { + tenant.Status.State = v1alpha1.StateFailed + logger.Error(errors.WithStack(err), "failed to check bridge connection", "bridge", bridge.Name) + if updateErr := r.Status().Update(ctx, tenant); updateErr != nil { + logger.Error(errors.WithStack(updateErr), "failed update tenant status", "tenant", tenant.Name) + return ctrl.Result{}, err + } + return ctrl.Result{}, err + } + } + logsourceNamespacesForTenant, err := r.getLogsourceNamespaceNamesForTenant(ctx, tenant) if err != nil { tenant.Status.State = v1alpha1.StateFailed @@ -452,6 +464,34 @@ func (r *RouteReconciler) getBridgesForTenant(ctx context.Context, tenantName st return } +func (r *RouteReconciler) getTenants(ctx context.Context, listOpts *client.ListOptions) ([]v1alpha1.Tenant, error) { + var tenants v1alpha1.TenantList + if err := r.Client.List(ctx, &tenants, listOpts); client.IgnoreNotFound(err) != nil { + return nil, err + } + + return tenants.Items, nil +} + +func (r *RouteReconciler) checkBridgeConnection(ctx context.Context, tenantName string, bridge *v1alpha1.Bridge) error { + for _, tenant := range []string{bridge.Spec.SourceTenant, bridge.Spec.TargetTenant} { + if tenant != tenantName { + listOpts := &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector(tenantNameField, tenant), + } + tenant, err := r.getTenants(ctx, listOpts) + if err != nil { + return err + } + if len(tenant) == 0 { + return errors.Errorf("bridge %s has a dangling tenant reference %s", bridge.Name, tenant) + } + } + } + + return nil +} + func normalizeNamespaceSlice(inputList []apiv1.Namespace) []apiv1.Namespace { allKeys := make(map[string]bool) uniqueList := []apiv1.Namespace{}