feat: refactor TenantResources (Replications)#1841
feat: refactor TenantResources (Replications)#1841oliverbaehler wants to merge 32 commits intoprojectcapsule:mainfrom
Conversation
…nantresource-impersonation
…nantresource-impersonation
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>
There was a problem hiding this comment.
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 useStatus.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.
| 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()) |
There was a problem hiding this comment.
Log message has a typo: "chache" → "cache".
| 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 | ||
| } |
There was a problem hiding this comment.
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.
| apiVersion: v1 | ||
| kind: ServiceAccount | ||
| metadata: | ||
| name: build-robot:hello |
There was a problem hiding this comment.
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.
| name: build-robot:hello | |
| name: build-robot-hello |
| 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) | ||
| } |
There was a problem hiding this comment.
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.
| 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 | ||
| } | ||
|
|
There was a problem hiding this comment.
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.
| @@ -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 | |||
| } | |||
There was a problem hiding this comment.
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.
| 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 |
There was a problem hiding this comment.
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.
|
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. |
There was a problem hiding this comment.
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 mixesapiandrbactypes 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) | |||
There was a problem hiding this comment.
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.
| userIsAdmin := users.IsAdminUser(req, h.cfg.Administrators()) | ||
|
|
||
| log.Info("Mutating HANDLER 1") |
There was a problem hiding this comment.
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.
| if !userIsAdmin && !users.IsCapsuleUser(ctx, c, h.cfg, req.UserInfo.Username, req.UserInfo.Groups) { | ||
| return nil | ||
| } | ||
|
|
||
| log.Info("Mutating HANDLER 2") |
There was a problem hiding this comment.
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.
| } | ||
|
|
||
| log.Info("Mutating HANDLER 3") |
There was a problem hiding this comment.
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.
| if tnt == nil && userIsAdmin { | ||
| return nil | ||
| } | ||
|
|
||
| log.Info("Mutating HANDLER 4") |
There was a problem hiding this comment.
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.
| } | ||
|
|
||
| sort.Slice(hooks, func(i, j int) bool { return hooks[i].Name < hooks[j].Name }) | ||
| controllerutil.SetOwnerReference(r.configuration.GetConfigObject(), obj, r.client.Scheme()) |
There was a problem hiding this comment.
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).
| controllerutil.SetOwnerReference(r.configuration.GetConfigObject(), obj, r.client.Scheme()) | |
| if err := controllerutil.SetOwnerReference(r.configuration.GetConfigObject(), obj, r.client.Scheme()); err != nil { | |
| return err | |
| } |
| kind: ClusterRoleBinding | ||
| metadata: | ||
| name: capsule-tenant-replications-2 | ||
| subjects: | ||
| - kind: User | ||
| name: alice | ||
| roleRef: | ||
| kind: ClusterRole | ||
| name: cluster-admin |
There was a problem hiding this comment.
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.
| .PHONY: ko-build-helper-labler | ||
| ko-build-helper-labler: ko |
There was a problem hiding this comment.
Typo in target name: labler should be labeler to match intent and avoid confusion when invoking make targets.
|
|
||
| .PHONY: ko-build-all | ||
| ko-build-all: ko-build-capsule | ||
| ko-build-all: ko-build-capsule ko-build-helper-labler |
There was a problem hiding this comment.
Typo in target name: labler should be labeler to match intent and avoid confusion when invoking make targets.
| .PHONY: ko-build-helper-labler | ||
| ko-build-helper-labler: ko |
There was a problem hiding this comment.
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.
| kind: ClusterRole | ||
| metadata: | ||
| name: {{ include "capsule.fullname" $ }}-resourcepoolclaims | ||
| name: capsule:{{ include "capsule.fullname" $ }}:resourcepoolclaims |
There was a problem hiding this comment.
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.
| kind: ClusterRole | ||
| metadata: | ||
| name: {{ include "capsule.fullname" $ }}-resources | ||
| name: capsule:{{ include "capsule.fullname" $ }}:tenantresources |
There was a problem hiding this comment.
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.
| kind: ClusterRole | ||
| metadata: | ||
| name: {{ include "capsule.crds.name" . }} | ||
| name: capsule:{{ .Release.Name }}:crds |
There was a problem hiding this comment.
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).
| kind: ClusterRoleBinding | ||
| metadata: | ||
| name: {{ include "capsule.crds.name" . }} | ||
| name: capsule:{{ .Release.Name }}:crds |
There was a problem hiding this comment.
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).
| apiGroup: rbac.authorization.k8s.io | ||
| kind: ClusterRole | ||
| name: {{ include "capsule.crds.name" . }} | ||
| name: capsule:{{ .Release.Name }}:crds |
There was a problem hiding this comment.
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).
| CHART ?= "./charts/capsule" | ||
| CHART_VERSION ?= "./charts/capsule" |
There was a problem hiding this comment.
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.
| --install \ | ||
| --namespace capsule-system \ | ||
| --create-namespace \ | ||
| --version=$(CHART_VERSION) \ |
There was a problem hiding this comment.
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.
| --version=$(CHART_VERSION) \ |
|
|
||
| .PHONY: ko-build-all | ||
| ko-build-all: ko-build-capsule | ||
| ko-build-all: ko-build-capsule ko-build-helper-labler |
There was a problem hiding this comment.
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.
|
|
||
| // +kubebuilder:object:root=true | ||
| // +kubebuilder:subresource:status | ||
| // +kubebuilder:printcolumn:name="Limit",type="string",JSONPath=".status.spec.limit",description="The total limit available" |
There was a problem hiding this comment.
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\".
| // +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" |
| if err := kubeClient.List(ctx, list); err != nil { | ||
| return nil, err | ||
| } |
There was a problem hiding this comment.
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.
Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
| 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 |
| TenantStateActive tenantState = "Active" | ||
| TenantStateCordoned tenantState = "Cordoned" | ||
| TerminatingStateCordoned tenantState = "Terminating" |
| CoreOwnerSpec: rbac.CoreOwnerSpec{ | ||
| UserSpec: rbac.UserSpec{ | ||
| Name: "bob", | ||
| Kind: "Group", | ||
| Kind: "User", | ||
| }, |
| IPBlock: &networkingv1.IPBlock{ | ||
| CIDR: "192.168.0.0/12", | ||
| CIDR: "192.160.0.0/12", | ||
| }, |
| IPBlock: &networkingv1.IPBlock{ | ||
| CIDR: "0.0.0.0/0", | ||
| Except: []string{ | ||
| "192.168.0.0/12", | ||
| "192.160.0.0/12", | ||
| }, |
| sleep 2 | ||
|
|
||
| TOKEN=$(kubectl -n "$NAMESPACE" get secret "$SECRET_NAME" \ | ||
| -o jsonpath='{.data.token}' | base64 -d) | ||
|
|
No description provided.