feat: add tenant and managed namespace count to status of capsuleconfiguration#1935
feat: add tenant and managed namespace count to status of capsuleconfiguration#1935sandert-k8s wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR adds status observedGeneration tracking across multiple Capsule CRDs/controllers, and extends CapsuleConfiguration status to aggregate tenant and managed-namespace counts (with additional watches/predicates to keep it updated).
Changes:
- Add
status.observedGenerationfields to several APIs/CRDs and set them during status updates in controllers. - Update
CapsuleConfigurationreconciliation to computetenantCount/managedNamespaceCount, set a Ready condition, and requeue on Tenant create/delete andstatus.sizechanges. - Add/extend E2E coverage to assert
status.observedGeneration == metadata.generation.
Reviewed changes
Copilot reviewed 31 out of 32 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/runtime/predicates/tenant_change.go | Adds a predicate to trigger reconciles on Tenant create/delete and status.size changes. |
| internal/controllers/tenant/status.go | Sets Tenant.status.observedGeneration during status updates. |
| internal/controllers/rulestatus/manager.go | Sets RuleStatus.status.observedGeneration during status updates. |
| internal/controllers/resources/namespaced.go | Sets TenantResource.status.observedGeneration during status updates. |
| internal/controllers/resources/global.go | Sets GlobalTenantResource.status.observedGeneration during status updates. |
| internal/controllers/resourcepools/pool_controller.go | Sets ResourcePool.status.observedGeneration during status updates. |
| internal/controllers/resourcepools/claim_controller.go | Sets ResourcePoolClaim.status.observedGeneration and adjusts Ready condition input. |
| internal/controllers/customquotas/global_custom_quota_controller.go | Sets GlobalCustomQuota.status.observedGeneration during status updates. |
| internal/controllers/customquotas/custom_quota_controller.go | Sets CustomQuota.status.observedGeneration during status updates. |
| internal/controllers/cfg/status/manager.go | Watches Tenants, aggregates counts into CapsuleConfiguration.status, and sets Ready condition + observedGeneration. |
| e2e/utils_test.go | Extends Tenant readiness helper to assert observedGeneration matches generation. |
| e2e/observed_generation_test.go | Adds E2E specs for observedGeneration on Tenant/CapsuleConfiguration/RuleStatus. |
| charts/capsule/crds/capsule.clastix.io_tenants.yaml | Adds status.observedGeneration to the Tenant CRD schema. |
| charts/capsule/crds/capsule.clastix.io_tenantresources.yaml | Adds status.observedGeneration to the TenantResource CRD schema. |
| charts/capsule/crds/capsule.clastix.io_tenantowners.yaml | Adds status.observedGeneration to the TenantOwner CRD schema. |
| charts/capsule/crds/capsule.clastix.io_rulestatuses.yaml | Adds status.observedGeneration to the RuleStatus CRD schema. |
| charts/capsule/crds/capsule.clastix.io_resourcepools.yaml | Adds status.observedGeneration to the ResourcePool CRD schema. |
| charts/capsule/crds/capsule.clastix.io_resourcepoolclaims.yaml | Adds status.observedGeneration to the ResourcePoolClaim CRD schema. |
| charts/capsule/crds/capsule.clastix.io_globaltenantresources.yaml | Adds status.observedGeneration to the GlobalTenantResource CRD schema. |
| charts/capsule/crds/capsule.clastix.io_globalcustomquotas.yaml | Adds status.observedGeneration to the GlobalCustomQuota CRD schema. |
| charts/capsule/crds/capsule.clastix.io_customquotas.yaml | Adds status.observedGeneration to the CustomQuota CRD schema. |
| charts/capsule/crds/capsule.clastix.io_capsuleconfigurations.yaml | Adds printer columns + status schema fields for counts/conditions/observedGeneration. |
| api/v1beta2/tenantresource_types.go | Adds ObservedGeneration to common status for TenantResource-like APIs. |
| api/v1beta2/tenantowner_types.go | Adds ObservedGeneration to TenantOwner status. |
| api/v1beta2/tenant_status.go | Adds ObservedGeneration to Tenant status. |
| api/v1beta2/rule_status_type.go | Adds ObservedGeneration to RuleStatus status and renames the status type. |
| api/v1beta2/resourcepoolclaim_types.go | Adds ObservedGeneration to ResourcePoolClaim status. |
| api/v1beta2/resourcepool_status.go | Adds ObservedGeneration to ResourcePool status. |
| api/v1beta2/customquota_status.go | Adds ObservedGeneration to CustomQuota status. |
| api/v1beta2/capsuleconfiguration_types.go | Adds kubebuilder printer columns for CapsuleConfiguration. |
| api/v1beta2/capsuleconfiguration_status.go | Adds conditions + counts + observedGeneration to CapsuleConfiguration status. |
Files not reviewed (1)
- api/v1beta2/zz_generated.deepcopy.go: Language not supported
Comments suppressed due to low confidence (2)
internal/controllers/tenant/status.go:1
- In a RetryOnConflict-style status update,
instance.GetGeneration()can be stale relative to the freshly-fetchedlatestobject. This can persist an out-of-datestatus.observedGenerationeven though you're updating the current object. Prefer settinglatest.Status.ObservedGenerationfromlatest.GetGeneration()(and, if any conditions use generation, base them onlatestas well).
pkg/runtime/predicates/tenant_change.go:1 - The comment says
namespaceCount changes, but the controller status field introduced/used elsewhere ismanagedNamespaceCount(aggregated from Tenantstatus.size). Consider updating the wording to match the exposed status field name to avoid confusion for future maintainers.
912930e to
75f6fe6
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 32 changed files in this pull request and generated 5 comments.
Files not reviewed (1)
- api/v1beta2/zz_generated.deepcopy.go: Language not supported
Comments suppressed due to low confidence (1)
pkg/runtime/predicates/tenant_change.go:1
- The comment mentions
namespaceCount changes, but the aggregated field introduced in this PR ismanagedNamespaceCount(and it’s derived fromstatus.size). Updating the wording to match the actual status field name would reduce confusion when correlating predicates, reconcile triggers, andCapsuleConfigurationstatus.
75f6fe6 to
ebfbc93
Compare
ebfbc93 to
141a710
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 32 changed files in this pull request and generated 3 comments.
Files not reviewed (1)
- api/v1beta2/zz_generated.deepcopy.go: Language not supported
Comments suppressed due to low confidence (2)
api/v1beta2/rule_status_type.go:1
- Renaming the exported type from
RuleStatusSpectoRuleStatusStatusis a compile-time breaking change for any Go consumers importingapi/v1beta2. If the old name was already part of the public API surface, consider preserving backwards compatibility via a type alias (e.g.,type RuleStatusSpec = RuleStatusStatus) or keeping the original exported type name and only adjusting field semantics/comments.
// Copyright 2020-2026 Project Capsule Authors
pkg/runtime/predicates/tenant_change.go:1
- The comment says
namespaceCount changes, but in this PR the aggregated field ismanagedNamespaceCountand it is derived fromTenant.Status.Size. Updating the comment to match the public status field name will avoid confusion about what’s being tracked.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 32 changed files in this pull request and generated 4 comments.
Files not reviewed (1)
- api/v1beta2/zz_generated.deepcopy.go: Language not supported
Comments suppressed due to low confidence (1)
pkg/runtime/predicates/tenant_change.go:1
- The comment refers to
namespaceCount, but the config status field added in this PR ismanagedNamespaceCount(and the predicate isstatus.size-driven). Consider updating the wording to match the actual field name to avoid confusion when tracing why a reconcile was enqueued.
2ff38e1 to
ed3ae8a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 33 changed files in this pull request and generated 4 comments.
Files not reviewed (1)
- api/v1beta2/zz_generated.deepcopy.go: Language not supported
Comments suppressed due to low confidence (2)
internal/controllers/tenant/status.go:1
ObservedGenerationis being set frominstance.GetGeneration()whilelatestis the object that will be written. In retry-on-conflict patterns (or if the object generation advanced between fetch and status update), this can persist a staleobservedGenerationthat no longer corresponds to the resource you’re updating. A safer approach is to (a) setObservedGenerationfromlatest.GetGeneration()and/or (b) detectlatest.GetGeneration() != instance.GetGeneration()and abort/requeue so you don’t mark a newer generation as “observed” without reconciling it.
pkg/runtime/predicates/tenant_change.go:1- The wording “namespaceCount changes” is a bit ambiguous given the
CapsuleConfigurationfield is namedManagedNamespaceCountand the predicate is based onTenant.status.size. Consider clarifying this to something like “managed namespace count changes” (or explicitly “sum of Tenant.status.size changes”) to reduce confusion about what is being counted.
…iguration Signed-off-by: sandert-k8s <sandert98@gmail.com>
ed3ae8a to
4c2167c
Compare
| tnt := &capsulev1beta2.Tenant{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: "e2e-cfg-counters-tnt", | ||
| Labels: map[string]string{ | ||
| "env": "e2e", | ||
| }, | ||
| }, | ||
| Spec: capsulev1beta2.TenantSpec{ | ||
| Owners: rbac.OwnerListSpec{ | ||
| { | ||
| CoreOwnerSpec: rbac.CoreOwnerSpec{ | ||
| UserSpec: rbac.UserSpec{ | ||
| Name: "e2e-cfg-counters-owner", | ||
| Kind: "User", | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| } |
| EventuallyCreation(func() error { | ||
| tnt.ResourceVersion = "" | ||
|
|
||
| return k8sClient.Create(context.TODO(), tnt) | ||
| }).Should(Succeed()) |
| var namespaceCount uint64 | ||
| for i := range tenantList.Items { | ||
| namespaceCount += uint64(tenantList.Items[i].Status.Size) | ||
| } | ||
|
|
||
| tc := int64(len(tenantList.Items)) | ||
| mnc := int64(namespaceCount) | ||
| instance.Status.TenantCount = &tc | ||
| instance.Status.ManagedNamespaceCount = &mnc |
| latest.Status = instance.Status | ||
| latest.Status.ObservedGeneration = instance.GetGeneration() | ||
|
|
||
| readyCondition := capmeta.NewReadyCondition(latest) | ||
| readyCondition.ObservedGeneration = instance.GetGeneration() |
Add objects to status of CapsuleConfiguration:
Added those as well to the
kubectl get CapsuleConfigurationoutput.