Add status conditions to MCPToolConfig CRD#4474
Conversation
MCPToolConfig was the only CRD in the operator without standard Kubernetes conditions in its status. This adds a Conditions field and sets a Valid condition during reconciliation, bringing it in line with MCPServer, EmbeddingServer, and MCPExternalAuthConfig. Closes #4472 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Keep condition messages user-facing and static. The underlying error is already logged via logger.Error and returned for requeue. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verify condition-setting, hash tracking, referencing server updates, and finalizer-based deletion protection using envtest. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@claude Please review this PR for major and critical issues only — correctness bugs, security concerns, data loss risks, or architectural problems. Do not raise stylistic, minor, or low-level issues. After your review, please recommend whether this PR should be approved or if changes are needed. |
|
Claude finished @ChrisJBurns's task in 2m 31s —— View job PR Review: Add status conditions to MCPToolConfig CRD
Assessment: ApproveThe implementation is correct, consistent with the codebase pattern, and well-tested. I found one behavioral divergence from the reference implementation worth flagging, but it is not a blocking issue. One behavioral divergence from MCPExternalAuthConfigIn
// Hash is written to status BEFORE checking if findReferencingMCPServers succeeds
toolConfig.Status.ConfigHash = configHash
toolConfig.Status.ObservedGeneration = toolConfig.Generation
referencingServers, err := r.findReferencingMCPServers(ctx, toolConfig)
if err != nil {
// ...sets Valid=False...
r.Status().Update(ctx, toolConfig) // <-- persists the new hash + Valid=False
return ctrl.Result{}, err
}The reference implementation ( The ToolConfig controller persists the new hash even on failure. On the next requeue the hash matches, so Everything else looks correct
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4474 +/- ##
==========================================
- Coverage 69.64% 69.64% -0.01%
==========================================
Files 491 491
Lines 50304 50324 +20
==========================================
+ Hits 35036 35046 +10
- Misses 12580 12590 +10
Partials 2688 2688 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Move ConfigHash and ObservedGeneration writes after the findReferencingMCPServers call so a transient failure requeues into handleConfigHashChange and MCPServer annotation updates are not permanently skipped. Also regenerate CRD API docs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Claude finished @ChrisJBurns's task in 41s —— View job Re-review: Verifying fix for hash persistence divergence
Concern resolved — fix is correctCommit 277cfc9 addresses the divergence exactly as needed. The ordering in // 1. Lookup first (lines 124–131)
referencingServers, err := r.findReferencingMCPServers(ctx, toolConfig)
if err != nil {
// Return WITHOUT calling Status().Update() and WITHOUT writing the hash.
// Error will requeue; next attempt re-enters handleConfigHashChange.
return ctrl.Result{}, fmt.Errorf("failed to find referencing MCPServers: %w", err)
}
// 2. Only set hash in memory after successful lookup (lines 133–135)
toolConfig.Status.ConfigHash = configHash
toolConfig.Status.ObservedGeneration = toolConfig.Generation
// 3. Persist to API server (lines 146–149)
if err := r.Status().Update(ctx, toolConfig); err != nil { ... }The comment at line 128–130 also documents the intent clearly:
This now matches the MCPExternalAuthConfig pattern exactly. On a transient Recommendation: ApproveNo remaining concerns. The implementation is correct, the divergence from the reference pattern is resolved, and the fix is well-commented. |
Summary
MCPToolConfig was the only CRD in the operator without standard Kubernetes conditions in its status struct. Every other CRD (MCPServer, EmbeddingServer, MCPExternalAuthConfig) uses
Conditions []metav1.Conditionto report validation state and readiness. This adds the same pattern to MCPToolConfig for consistency, enabling generic tooling and operators to check.status.conditionsuniformly across all CRDs.Conditionsfield toMCPToolConfigStatuswith standard kubebuilder list markersConditionToolConfigValidtype and reason constantsValid=Trueon successful reconciliation,Valid=Falseon error paths (with static messages to avoid leaking errors into conditions)Closes #4472
Type of change
Test plan
task test)task operator-test-integration) — new suite atcmd/thv-operator/test-integration/mcp-toolconfig/task lint-fix)Changes
cmd/thv-operator/api/v1alpha1/toolconfig_types.goConditionsfield and condition constantscmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.gocmd/thv-operator/controllers/toolconfig_controller.gocmd/thv-operator/controllers/toolconfig_controller_test.gocmd/thv-operator/test-integration/mcp-toolconfig/suite_test.gocmd/thv-operator/test-integration/mcp-toolconfig/mcptoolconfig_controller_integration_test.godeploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_mcptoolconfigs.yamldeploy/charts/operator-crds/templates/toolhive.stacklok.dev_mcptoolconfigs.yamlDoes this introduce a user-facing change?
MCPToolConfig resources now report a
Validcondition in.status.conditions, visible viakubectl get mcptoolconfig -o yaml. This is additive and does not affect existing manifests.Special notes for reviewers
The implementation closely follows the MCPExternalAuthConfig controller pattern since both CRDs share the same status shape (
ObservedGeneration,ConfigHash,ReferencingServers). Error messages in conditions are kept static to avoid leaking internal errors — the underlying errors are logged and returned for requeue.Generated with Claude Code