// Copyright 2020-2026 Project Capsule Authors // SPDX-License-Identifier: Apache-2.0 package tenant import ( "context" "fmt" "strconv" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2" "github.com/projectcapsule/capsule/pkg/api/meta" ) // Ensuring all the LimitRange are applied to each Namespace handled by the Tenant. // func (r *Manager) syncLimitRanges(ctx context.Context, log logr.Logger, tenant *capsulev1beta2.Tenant) error { // getting requested LimitRange keys //nolint:staticcheck keys := make([]string, 0, len(tenant.Spec.LimitRanges.Items)) //nolint:staticcheck for i := range tenant.Spec.LimitRanges.Items { keys = append(keys, strconv.Itoa(i)) } return runForTenantNamespaces(ctx, tenant, func(ctx context.Context, namespace string) error { return r.syncLimitRange(ctx, log, tenant, namespace, keys) }) } func (r *Manager) syncLimitRange( ctx context.Context, log logr.Logger, tenant *capsulev1beta2.Tenant, namespace string, keys []string, ) (err error) { if err = r.pruningResources(ctx, namespace, keys, &corev1.LimitRange{}); err != nil { return err } //nolint:staticcheck for i, spec := range tenant.Spec.LimitRanges.Items { target := &corev1.LimitRange{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("capsule-%s-%d", tenant.Name, i), Namespace: namespace, }, } var res controllerutil.OperationResult res, err = controllerutil.CreateOrUpdate(ctx, r.Client, target, func() (err error) { labels := target.GetLabels() if labels == nil { labels = map[string]string{} } labels[meta.NewManagedByCapsuleLabel] = meta.ValueController labels[meta.NewTenantLabel] = tenant.Name labels[meta.LimitRangeLabel] = strconv.Itoa(i) // Remove Legacy labels delete(labels, meta.TenantLabel) target.SetLabels(labels) target.Spec = spec return controllerutil.SetControllerReference(tenant, target, r.Scheme()) }) if err != nil { if apierrors.HasStatusCause(err, corev1.NamespaceTerminatingCause) { log.Info( "skipping LimitRange sync because namespace is terminating", "name", target.Name, "namespace", target.Namespace, "tenant", tenant.Name, ) return nil } return err } log.Info("LimitRange sync result: "+string(res), "name", target.Name, "namespace", target.Namespace) } return nil }