Skip to content

feat: refactor TenantResources (Replications)#1841

Open
oliverbaehler wants to merge 32 commits intoprojectcapsule:mainfrom
oliverbaehler:feat/tenantresource-impersonation
Open

feat: refactor TenantResources (Replications)#1841
oliverbaehler wants to merge 32 commits intoprojectcapsule:mainfrom
oliverbaehler:feat/tenantresource-impersonation

Conversation

@oliverbaehler
Copy link
Copy Markdown
Collaborator

No description provided.

oliverbaehler and others added 26 commits November 27, 2025 09:26
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: CorentinPtrl <pitrel.corentin@gmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
Copilot AI review requested due to automatic review settings February 10, 2026 08:48
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors Capsule’s TenantResource/GlobalTenantResource replication pipeline, adding impersonation support, new indexing/helpers, and reorganizing admission webhooks/routes and Helm chart configuration to support the new behavior.

Changes:

  • Refactor TenantResource / GlobalTenantResource API types, processing, indexing, and template context utilities.
  • Add impersonation REST/client plumbing (CapsuleConfiguration spec + cache + controller) and new “replicas” admission webhook handling.
  • Update Helm chart values/templates/CRDs and add multiple example manifests and scripts for local/dev usage.

Reviewed changes

Copilot reviewed 137 out of 140 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tnts.yaml Example ArgoCD RBAC + GlobalTenantResource template sample
tnt.yaml Example Tenant manifests
sops.yaml Example RBAC + GlobalTenantResource template sample
solar-test.yaml Example TenantResource replication test manifest
rolebinding-flux.yaml Example GlobalTenantResource rawItems for Flux/gitops
rbac.yaml Example RBAC + GlobalTenantResource replication config
rbac-2.yaml Example ClusterRole/Binding manifest
pod.yaml Example Pod manifest
pkg/utils/maps.go Adds ToMap helper using unstructured converter
pkg/users/user_group_test.go Moves tests to external package usage (users_test)
pkg/users/serviceaccounts.go Adds SA identity/groups helpers + impersonated client creator
pkg/users/is_capsule_user.go Switches controller SA detection to configuration helper
pkg/tenant/namespaces.go Adds namespace collection by label selector helper
pkg/template/types.go Changes MissingKey option enum/value naming
pkg/template/reference_context.go Removes old TemplateContext implementation (moved)
pkg/template/reference.go Refactors ResourceReference (namespace now string) and templating
pkg/template/funcmap_test.go Adds tests for new template helper functions
pkg/template/funcmap.go Refactors func map, removes env funcs, adds deterministic UUID
pkg/template/fast.go Minor formatting change
pkg/template/context.go New TemplateContext gathering + JSON self-templating
pkg/runtime/sanitize/object.go Minor formatting change
pkg/runtime/predicates/utils_test.go Adds tests for label equality/change helpers
pkg/runtime/predicates/utils.go Adds LabelsEqual / LabelsChanged helpers
pkg/runtime/predicates/reconcile_requested.go Minor formatting change
pkg/runtime/predicates/labels_matching.go Minor formatting change
pkg/runtime/predicates/config_change_test.go Updates copyright year
pkg/runtime/indexers/tenantresource/namespaced_serviceaccount.go Adds TenantResource serviceAccount indexer
pkg/runtime/indexers/tenantresource/namespaced_items.go Renames/adjusts processed-items indexer + key format
pkg/runtime/indexers/tenantresource/global_serviceaccount_test.go Adds tests for GlobalTenantResource serviceAccount indexer
pkg/runtime/indexers/tenantresource/global_serviceaccount.go Adds GlobalTenantResource serviceAccount indexer
pkg/runtime/indexers/tenantresource/global_items.go Updates processed-items indexer field/key
pkg/runtime/indexers/tenantresource/const.go Defines index field key constants
pkg/runtime/indexers/tenant/owner.go Uses constant for owner kind index field
pkg/runtime/indexers/tenant/namespaces.go Uses constant for namespaces index field
pkg/runtime/indexers/tenant/const.go Adds tenant index field constants
pkg/runtime/indexers/indexer.go Registers new tenantresource indexers; removes old ones
pkg/runtime/handlers/is_not_privileged.go Adds handler wrapper to bypass checks for admins/controller SA
pkg/runtime/gvk/resource_key_test.go Adds tests for key extraction from unstructured
pkg/runtime/gvk/resource_key.go Adds unstructured -> ResourceKey helper
pkg/runtime/gvk/resource_id.go Adds ResourceID / key helpers for replication identity
pkg/runtime/configuration/utils.go Adds helper to load CA cert from Secret
pkg/runtime/configuration/env.go Centralizes controller env var names + controller SA checks
pkg/runtime/configuration/configuration.go Extends Configuration interface with impersonation client methods
pkg/runtime/configuration/client.go Refactors CapsuleConfiguration loader; adds ServiceAccountClient builder
pkg/runtime/client/ignore.go Minor formatting change
pkg/runtime/client/apply.go Renames/apply helper to PatchApply and simplifies implementation
pkg/runtime/cert/errors.go Removes CA validity error types
pkg/runtime/cert/ca_test.go Moves tests to external package (cert_test)
pkg/api/scope.go Introduces ResourceScope type/constants
pkg/api/processor/processor.go Introduces processor structs/options for replication pipeline
pkg/api/processor/accumulator.go Adds accumulator structs/helpers for generated objects tracking
pkg/api/meta/ownerreference.go Minor formatting change
pkg/api/meta/names.go Adds helper for pool ResourceQuota name
pkg/api/meta/managers.go Adds helpers for Capsule-managed field owner detection
pkg/api/meta/labels.go Adds resources label constant; formatting
pkg/api/meta/finalizers.go Adds legacy resource finalizer constant
pkg/api/meta/const.go Adds ValueControllerResources constant
pkg/api/meta/conditions.go Adds Reconciling reason + helper to create reconciling condition
pkg/api/allowed_list_test.go Import order fix
nsresource.yaml Example resource + TenantResource manifest
ns.yaml Example TenantResource with templates/raw items
kubeconfig-kind.yaml Example kubeconfig (contains embedded key material)
internal/webhook/tenantresource/objects.go Removes old tenantresource objects webhook implementation
internal/webhook/route/tenantresource_objs.go Removes tenantresource objects webhook route
internal/webhook/route/misc.go Removes old misc routes (migrated)
internal/webhook/route/generic.go Adds generic routes including replicas + managed handlers
internal/webhook/generic/replicas.go Adds validating handler for replicated/managed resources updates/deletes
internal/webhook/generic/managed.go Renames misc->generic and tightens denial messages
internal/webhook/generic/custom_resource_quota.go Renames misc->generic package
internal/webhook/generic/cordoning.go Renames misc->generic package
internal/webhook/generic/assignment.go Renames misc->generic package
internal/webhook/cfg/warnings.go Converts to typed handler to avoid decoder re-decode
internal/webhook/cfg/serviceaccount.go Adds validation for impersonation global default SA fields
internal/webhook/cfg/handler.go Adds typed handler multiplexer for CapsuleConfiguration admission
internal/metrics/tenantresource_recorder.go Adds TenantResource condition metrics recorder
internal/metrics/globaltenantresource_recorder.go Adds GlobalTenantResource condition metrics recorder
internal/controllers/utils/gvk.go Removes old RESTMapping helper
internal/controllers/tenant/manager.go Adjusts reconcile error returned; explicitly clears deferred error
internal/controllers/servicelabels/service.go Sets controller name for service controller
internal/controllers/servicelabels/endpoint_slices.go Sets controller name for endpointslices controller
internal/controllers/serviceaccounts/manager.go Adds controller to invalidate impersonation cache on SA changes
internal/controllers/resources/utils.go Adds field owner + selector utilities for resources controller
internal/controllers/resources/processor.go Removes old monolithic processor implementation
internal/controllers/resources/manager.go Adds controller manager wiring for global/namespaced resources controllers
internal/controllers/rbac/manager.go Minor const formatting
internal/controllers/cfg/manager.go Passes REST config into configuration builder; minor client calls
internal/controllers/admission/validating.go Switches to PatchApply helper
internal/controllers/admission/mutating.go Switches to PatchApply helper
internal/cache/impersonation_clients.go Adds impersonation client cache
hack/kubeconfig-for-sa.sh Adds script to generate SA kubeconfig for kind/dev
hack/distro/capsule/example-setup/tenants.yaml Updates example tenants (resourceQuotas/limitRanges/owners)
hack/distro/capsule/example-setup/resource.yaml Updates example GlobalTenantResource and adds gitops-owners
hack/distro/argocd/release.flux.yaml Adds ArgoCD health/actions customizations for TenantResource/GTR
go.mod Adds deps (sprout/toml/flux/ssa/yaml/jsonpatch), updates indirects
global.yaml Example GlobalTenantResource with templates/context
example.yaml Example Tenant + TenantOwner manifest
e2e/tenantresource_test.go Updates e2e types to new template.ResourceReference + common spec
e2e/tenant_resources_changes_test.go Expands e2e tamper tests using impersonated clients + RBAC setup
e2e/suite_test.go Adds helper for impersonated typed clientset
e2e/new_namespace_test.go Adds deletion test using impersonated owner
e2e/globaltenantresource_test.go Updates e2e types to new template.ResourceReference + common spec
e2e/config_client_test.go Adds e2e tests for ServiceAccountClient behavior
context.yaml Example GlobalTenantResource template with missingKey option
cms.yaml Example ConfigMaps for replication scenarios
cmd/main.go Wires new controllers/webhooks/caches; adds env var checks
charts/capsule/values.yaml Adds CRD-exclusive toggles, minimal/strict RBAC options, webhook updates
charts/capsule/values.schema.json Adds schema for impersonation + strict RBAC + descriptions
charts/capsule/templates/validatingwebhookconfiguration.yaml Routes misc→generic; adds replicas webhook
charts/capsule/templates/serviceaccount.yaml Allows SA creation when CRDs exclusive + createRBAC
charts/capsule/templates/rbac.yaml Adds minimal aggregated controller RBAC mode; renames bindings
charts/capsule/templates/rbac-tenants.yaml Renames tenant-facing ClusterRoles
charts/capsule/templates/mutatingwebhookconfiguration.yaml Routes misc→generic for tenant assignment
charts/capsule/templates/dashboards/diagnostics.yaml Adds createDiagnostics gating; updates dashboard glob path
charts/capsule/templates/crd-lifecycle/rbac.yaml Renames CRD lifecycle RBAC resources
charts/capsule/templates/configuration.yaml Adds gating for createConfig; renders impersonation config
charts/capsule/crds/capsule.clastix.io_capsuleconfigurations.yaml Adds admission ignores + impersonation schema
charts/capsule/README.md Updates values documentation for refactors/additions
binding.yaml Example ClusterRoleBinding granting cluster-admin
api/v1beta2/tenantresource_types.go Major refactor of TenantResource common spec/status + processed items
api/v1beta2/tenantresource_namespaced.go Refactors namespaced TenantResource spec/status with common structs
api/v1beta2/tenantresource_global_func.go Adds helper to assign/sort selected tenants
api/v1beta2/tenantresource_global.go Refactors GlobalTenantResource spec/status (scope, serviceAccount)
api/v1beta2/tenant_func_test.go Moves tests to external package
api/v1beta2/resourcepoolclaim_func_test.go Moves tests to external package; adjusts types
api/v1beta2/resourcepool_func_test.go Moves tests to external package; adjusts types
api/v1beta2/resourcepool_func.go Uses new name helper for pool ResourceQuota
api/v1beta2/capsuleconfiguration_types.go Adds impersonation + admission ignore fields/types
account.yaml Example ServiceAccount manifest
Makefile Updates dev-setup/e2e-install helm flags; generates SA kubeconfig
.gitignore Ignores generated kubeconfig output
Comments suppressed due to low confidence (2)

pkg/runtime/indexers/tenantresource/const.go:9

  • The constant name/value suggest this indexer is for .spec.serviceAccount, but the indexer functions use Status.ServiceAccount. Consider renaming the index field key to reflect what’s indexed (e.g. status.serviceAccount) to avoid confusion and incorrect future usage.
    kubeconfig-kind.yaml:19
  • This file contains embedded kubeconfig material including client-key-data (a private key). Committing credentials, even for kind/local dev, risks accidental reuse/leak. Remove this file from the repo (or replace with a sanitized example that contains no secrets) and document generation via the helper script instead.

Comment on lines +46 to +48
r.Log.V(5).Info("checking chache references for serviceaccount", "name", request.Name, "namespace", request.Namespace)

r.Log.V(5).Info("client cache stats", "size", r.Cache.Stats())
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log message has a typo: "chache" → "cache".

Copilot uses AI. Check for mistakes.
Comment on lines 106 to 112
maps.Copy(annotations, cfg.Annotations)

obj.SetAnnotations(annotations)

if err := clt.CreateOrPatch(ctx, r.client, obj, meta.FieldManagerCapsuleController, true); err != nil {
if err := clt.PatchApply(ctx, r.client, obj, meta.FieldManagerCapsuleController, true); err != nil {
return err
}
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reconcileConfiguration builds a MutatingWebhookConfiguration but never assigns the computed hooks to obj.Webhooks before applying it. With server-side apply this will create/update a configuration without any webhooks. Set obj.Webhooks = hooks before calling PatchApply.

Copilot uses AI. Check for mistakes.
Comment thread account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot:hello
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kubernetes ServiceAccount names must be DNS-1123 labels; build-robot:hello (colon) is invalid and will be rejected by the API server. Use a valid name (e.g. build-robot-hello) if this manifest is meant to be applied.

Suggested change
name: build-robot:hello
name: build-robot-hello

Copilot uses AI. Check for mistakes.
Comment thread cmd/main.go
Comment on lines +136 to 144
if ns = os.Getenv(configuration.EnvironmentControllerNamespace); len(ns) == 0 {
setupLog.Error(fmt.Errorf("unable to determinate the Namespace Capsule is running on. Please export %s", configuration.EnvironmentControllerNamespace), "unable to start manager")
os.Exit(1)
}

if ns = os.Getenv(configuration.EnvironmentServiceaccountName); len(ns) == 0 {
setupLog.Error(fmt.Errorf("unable to determinate the ServiceAccount Capsule is running with. Please export %s", configuration.EnvironmentServiceaccountName), "unable to start manager")
os.Exit(1)
}
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ns variable is reused for both controller namespace and service account env vars. The second assignment overwrites the namespace, so later code (e.g. TLS secret lookup and controller setup) will use the service account name as the namespace. Use separate variables (e.g. controllerNamespace and controllerServiceAccount) and avoid overwriting the namespace value.

Copilot uses AI. Check for mistakes.
Comment thread pkg/runtime/configuration/client.go Outdated
Comment on lines +208 to +216
func (c *capsuleConfiguration) ServiceAccountClient(ctx context.Context) (client *rest.Config, err error) {
props := c.ServiceAccountClientProperties()

client = c.rest

if props.Endpoint != "" {
client.Host = c.rest.Host
}

Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServiceAccountClient returns c.rest directly and then mutates it (Host/TLS settings). This can unintentionally change the manager’s base REST config globally. It also sets client.Host to c.rest.Host when props.Endpoint is set (likely meant to use props.Endpoint). Return a copy (e.g. rest.CopyConfig(c.rest)) and set Host from props.Endpoint when provided.

Copilot uses AI. Check for mistakes.
Comment on lines 97 to 103
@@ -98,7 +98,7 @@ func (r *validatingReconciler) reconcileValidatingConfiguration(

obj.SetAnnotations(annotations)

if err := clt.CreateOrPatch(ctx, r.client, obj, meta.FieldManagerCapsuleController, true); err != nil {
if err := clt.PatchApply(ctx, r.client, obj, meta.FieldManagerCapsuleController, true); err != nil {
return err
}
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reconcileValidatingConfiguration builds a ValidatingWebhookConfiguration but never assigns the computed hooks to obj.Webhooks before applying it. With server-side apply this will create/update a configuration without any webhooks. Set obj.Webhooks = hooks (and similarly for mutating) before calling PatchApply.

Copilot uses AI. Check for mistakes.
Comment thread pkg/tenant/namespaces.go
Comment on lines +41 to +45
tntRequirement, err := labels.NewRequirement(meta.TenantLabel, selection.Equals, []string{tnt.GetName()})
if err != nil {
err = fmt.Errorf("unable to create requirement for Namespace filtering and resource replication", err)

return nil, err
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These fmt.Errorf calls pass an err argument but the format string has no %w/%v, so the underlying error is dropped. Use wrapping (e.g. fmt.Errorf("...: %w", err)) so callers can see and unwrap the root cause.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown

This pull request has been marked as stale because it has been inactive for more than 30 days. Please update this pull request or it will be automatically closed in 30 days.

@github-actions github-actions bot added the Stale label Mar 13, 2026
Copilot AI review requested due to automatic review settings March 24, 2026 16:26
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 178 out of 333 changed files in this pull request and generated 21 comments.

Comments suppressed due to low confidence (1)

api/v1beta2/tenant_func_test.go:1

  • This hunk introduces invalid Go syntax (Subjects: ,) and unmatched braces, which will break compilation. Please fix the struct literal and ensure the new test compiles and reflects the intended API types (it currently mixes api and rbac types in multiple places).
// Copyright 2020-2026 Project Capsule Authors

@@ -33,26 +34,36 @@ type handler struct {

func (h *handler) OnCreate(c client.Client, decoder admission.Decoder, recorder events.EventRecorder) handlers.Func {
return func(ctx context.Context, req admission.Request) *admission.Response {
log := log.FromContext(ctx)
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These unconditional informational logs add noise and don’t convey actionable information. Consider removing them or switching to debug verbosity with contextual fields (operation, namespace, user) so they are useful when troubleshooting.

Copilot uses AI. Check for mistakes.
userIsAdmin := users.IsAdminUser(req, h.cfg.Administrators())

log.Info("Mutating HANDLER 1")
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These unconditional informational logs add noise and don’t convey actionable information. Consider removing them or switching to debug verbosity with contextual fields (operation, namespace, user) so they are useful when troubleshooting.

Copilot uses AI. Check for mistakes.
if !userIsAdmin && !users.IsCapsuleUser(ctx, c, h.cfg, req.UserInfo.Username, req.UserInfo.Groups) {
return nil
}

log.Info("Mutating HANDLER 2")
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These unconditional informational logs add noise and don’t convey actionable information. Consider removing them or switching to debug verbosity with contextual fields (operation, namespace, user) so they are useful when troubleshooting.

Copilot uses AI. Check for mistakes.
}

log.Info("Mutating HANDLER 3")
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These unconditional informational logs add noise and don’t convey actionable information. Consider removing them or switching to debug verbosity with contextual fields (operation, namespace, user) so they are useful when troubleshooting.

Copilot uses AI. Check for mistakes.
if tnt == nil && userIsAdmin {
return nil
}

log.Info("Mutating HANDLER 4")
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These unconditional informational logs add noise and don’t convey actionable information. Consider removing them or switching to debug verbosity with contextual fields (operation, namespace, user) so they are useful when troubleshooting.

Copilot uses AI. Check for mistakes.
}

sort.Slice(hooks, func(i, j int) bool { return hooks[i].Name < hooks[j].Name })
controllerutil.SetOwnerReference(r.configuration.GetConfigObject(), obj, r.client.Scheme())
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

controllerutil.SetOwnerReference returns an error that is ignored here. Please handle the returned error and fail reconciliation if it occurs, otherwise you can end up with unmanaged webhook configurations (and also miss important runtime/scheme issues).

Suggested change
controllerutil.SetOwnerReference(r.configuration.GetConfigObject(), obj, r.client.Scheme())
if err := controllerutil.SetOwnerReference(r.configuration.GetConfigObject(), obj, r.client.Scheme()); err != nil {
return err
}

Copilot uses AI. Check for mistakes.
Comment thread binding.yaml
Comment on lines +4 to +12
kind: ClusterRoleBinding
metadata:
name: capsule-tenant-replications-2
subjects:
- kind: User
name: alice
roleRef:
kind: ClusterRole
name: cluster-admin
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This manifest grants cluster-admin to a user and is committed at repository root. If it’s intended as documentation, consider moving it under hack/ or docs/examples with explicit warnings; otherwise, it risks being applied accidentally and creating a serious privilege escalation.

Copilot uses AI. Check for mistakes.
Comment thread Makefile Outdated
Comment on lines +321 to +322
.PHONY: ko-build-helper-labler
ko-build-helper-labler: ko
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in target name: labler should be labeler to match intent and avoid confusion when invoking make targets.

Copilot uses AI. Check for mistakes.
Comment thread Makefile Outdated

.PHONY: ko-build-all
ko-build-all: ko-build-capsule
ko-build-all: ko-build-capsule ko-build-helper-labler
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in target name: labler should be labeler to match intent and avoid confusion when invoking make targets.

Copilot uses AI. Check for mistakes.
Comment thread Makefile Outdated
Comment on lines +321 to +322
.PHONY: ko-build-helper-labler
ko-build-helper-labler: ko
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title suggests a TenantResources replication refactor, but the diff includes broad changes to Helm templates, Makefile build targets, new root-level YAML examples, admission controller wiring, and configuration controllers. Consider updating the PR description to reflect the expanded scope or splitting non-replication changes into follow-up PRs to keep reviews and rollbacks manageable.

Copilot uses AI. Check for mistakes.
@github-actions github-actions bot removed the Stale label Mar 25, 2026
Copilot AI review requested due to automatic review settings March 26, 2026 21:57
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 149 out of 367 changed files in this pull request and generated 16 comments.

kind: ClusterRole
metadata:
name: {{ include "capsule.fullname" $ }}-resourcepoolclaims
name: capsule:{{ include "capsule.fullname" $ }}:resourcepoolclaims
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kubernetes object names (including ClusterRole) must be DNS-1123 compatible and cannot contain ':' characters. These names will be rejected by the API server. Use a DNS-safe delimiter (e.g., '-' or '.') such as capsule-{{ include \"capsule.fullname\" $ }}-resourcepoolclaims and capsule-{{ include \"capsule.fullname\" $ }}-tenantresources.

Copilot uses AI. Check for mistakes.
kind: ClusterRole
metadata:
name: {{ include "capsule.fullname" $ }}-resources
name: capsule:{{ include "capsule.fullname" $ }}:tenantresources
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kubernetes object names (including ClusterRole) must be DNS-1123 compatible and cannot contain ':' characters. These names will be rejected by the API server. Use a DNS-safe delimiter (e.g., '-' or '.') such as capsule-{{ include \"capsule.fullname\" $ }}-resourcepoolclaims and capsule-{{ include \"capsule.fullname\" $ }}-tenantresources.

Copilot uses AI. Check for mistakes.
kind: ClusterRole
metadata:
name: {{ include "capsule.crds.name" . }}
name: capsule:{{ .Release.Name }}:crds
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClusterRole/ClusterRoleBinding names cannot include ':' (must be DNS-1123). These resources will fail to install. Replace ':' with a DNS-safe delimiter (e.g., capsule-{{ .Release.Name }}-crds).

Copilot uses AI. Check for mistakes.
kind: ClusterRoleBinding
metadata:
name: {{ include "capsule.crds.name" . }}
name: capsule:{{ .Release.Name }}:crds
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClusterRole/ClusterRoleBinding names cannot include ':' (must be DNS-1123). These resources will fail to install. Replace ':' with a DNS-safe delimiter (e.g., capsule-{{ .Release.Name }}-crds).

Copilot uses AI. Check for mistakes.
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "capsule.crds.name" . }}
name: capsule:{{ .Release.Name }}:crds
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClusterRole/ClusterRoleBinding names cannot include ':' (must be DNS-1123). These resources will fail to install. Replace ':' with a DNS-safe delimiter (e.g., capsule-{{ .Release.Name }}-crds).

Copilot uses AI. Check for mistakes.
Comment thread Makefile
Comment on lines +162 to +163
CHART ?= "./charts/capsule"
CHART_VERSION ?= "./charts/capsule"
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHART_VERSION is set to a filesystem path, but Helm --version expects a chart version (semver) and is typically only used with chart repositories/OCI refs. This will likely break dev-setup. Also, the target name ko-build-helper-labler looks misspelled and is referenced by ko-build-all. Consider (1) removing --version when installing from a local chart directory or setting CHART_VERSION to an actual semver, and (2) renaming the target to ko-build-helper-labeler consistently.

Copilot uses AI. Check for mistakes.
Comment thread Makefile
--install \
--namespace capsule-system \
--create-namespace \
--version=$(CHART_VERSION) \
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHART_VERSION is set to a filesystem path, but Helm --version expects a chart version (semver) and is typically only used with chart repositories/OCI refs. This will likely break dev-setup. Also, the target name ko-build-helper-labler looks misspelled and is referenced by ko-build-all. Consider (1) removing --version when installing from a local chart directory or setting CHART_VERSION to an actual semver, and (2) renaming the target to ko-build-helper-labeler consistently.

Suggested change
--version=$(CHART_VERSION) \

Copilot uses AI. Check for mistakes.
Comment thread Makefile Outdated

.PHONY: ko-build-all
ko-build-all: ko-build-capsule
ko-build-all: ko-build-capsule ko-build-helper-labler
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHART_VERSION is set to a filesystem path, but Helm --version expects a chart version (semver) and is typically only used with chart repositories/OCI refs. This will likely break dev-setup. Also, the target name ko-build-helper-labler looks misspelled and is referenced by ko-build-all. Consider (1) removing --version when installing from a local chart directory or setting CHART_VERSION to an actual semver, and (2) renaming the target to ko-build-helper-labeler consistently.

Copilot uses AI. Check for mistakes.
Comment thread api/v1beta2/customquota_types.go Outdated

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Limit",type="string",JSONPath=".status.spec.limit",description="The total limit available"
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Limit JSONPath points to .status.spec.limit, but limit lives under .spec.limit (not inside status). This printcolumn will always be empty/incorrect. Update it to JSONPath=\".spec.limit\".

Suggested change
// +kubebuilder:printcolumn:name="Limit",type="string",JSONPath=".status.spec.limit",description="The total limit available"
// +kubebuilder:printcolumn:name="Limit",type="string",JSONPath=".spec.limit",description="The total limit available"

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +52
if err := kubeClient.List(ctx, list); err != nil {
return nil, err
}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kubeClient.List(ctx, list) is listing all objects for the target GVK cluster-wide, and only afterward filtering by namespace and label selectors in memory. For high-cardinality resources, this can be very expensive. Prefer pushing filters server-side where possible (e.g., client.InNamespace(...) when a single namespace is targeted and client.MatchingLabelsSelector{Selector: ...} for label selectors), or (when multiple namespaces are provided) listing per-namespace with selector options to reduce API payloads.

Copilot uses AI. Check for mistakes.
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
Copilot AI review requested due to automatic review settings April 17, 2026 12:41
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 139 out of 389 changed files in this pull request and generated 9 comments.

Comment on lines +141 to 147
AdditionalRoleBindings: []api.AdditionalRoleBindingsSpec{

func TestGetClusterRolesBySubject(t *testing.T) {

expected := map[string]map[string]api.TenantSubjectRoles{
"User": {
"user1": {
ClusterRoles: []string{"cluster-admin", "read-only"},
},
"user2": {
ClusterRoles: []string{"developer"},
},
"user3": {
ClusterRoles: []string{"cluster-admin"},
{
ClusterRoleName: "test",
Subjects: ,
},
},
- name: admission
protocol: TCP
targetPort: {{ .Values.manager.webhookPort }}
port: 9443
containerPort: {{ .Values.manager.webhookPort }}
- name: admission
protocol: TCP
containerPort: 9443

type PromotionRule struct {
// ClusterRoles granted to the promoted ServiceAccounts across the Tenant
// kubebuilder:validation:Minimum=1
Comment on lines +18 to +20
TenantStateActive tenantState = "Active"
TenantStateCordoned tenantState = "Cordoned"
TerminatingStateCordoned tenantState = "Terminating"
Comment thread e2e/new_namespace_test.go
Comment on lines +34 to 38
CoreOwnerSpec: rbac.CoreOwnerSpec{
UserSpec: rbac.UserSpec{
Name: "bob",
Kind: "Group",
Kind: "User",
},
Comment on lines 106 to 108
IPBlock: &networkingv1.IPBlock{
CIDR: "192.168.0.0/12",
CIDR: "192.160.0.0/12",
},
Comment on lines 117 to 121
IPBlock: &networkingv1.IPBlock{
CIDR: "0.0.0.0/0",
Except: []string{
"192.168.0.0/12",
"192.160.0.0/12",
},
Comment thread hack/kubeconfig-for-sa.sh
Comment on lines +33 to +37
sleep 2

TOKEN=$(kubectl -n "$NAMESPACE" get secret "$SECRET_NAME" \
-o jsonpath='{.data.token}' | base64 -d)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants