Files
capsule/internal/controllers/tenant/limitranges.go
T
Oliver Bähler e8ac32d364 feat: add administrator capabilities (#2049)
* feat: implement performance optimizations

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: add administrator capabilities

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* feat: add administrator capabilities

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

* chore

* feat: add administrator capabilities

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>

---------

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
2026-07-23 00:09:23 +02:00

104 lines
2.7 KiB
Go

// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0
//nolint:dupl
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 {
if err := r.runGarbageCollection(ctx, tenant, &corev1.LimitRange{}); err != nil {
return err
}
// 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 result controllerutil.OperationResult
result, 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.V(4).Info(
"skipping LimitRange sync because namespace is terminating",
"name", target.Name,
"namespace", target.Namespace,
"tenant", tenant.Name,
)
return nil
}
return err
}
log.V(4).Info("LimitRange sync result", "result", result, "name", target.Name, "namespace", target.Namespace)
}
return nil
}