Skip to content

Migrate Remaining VirtualMCPServer Fields to spec.config#3242

Merged
jerm-dro merged 19 commits intomainfrom
jerm/2026-01-09-remaining-migrations
Jan 13, 2026
Merged

Migrate Remaining VirtualMCPServer Fields to spec.config#3242
jerm-dro merged 19 commits intomainfrom
jerm/2026-01-09-remaining-migrations

Conversation

@jerm-dro
Copy link
Copy Markdown
Contributor

@jerm-dro jerm-dro commented Jan 9, 2026

Summary

This PR completes the migration of VirtualMCPServer CRD fields from the top-level spec into the nested spec.config structure, aligning with the platform-agnostic configuration model and consolidating validation logic.

Fixes #3125

Large PR Justification

Please review this PR commit-by-commit (10 commits total). Each commit is self-contained with its own tests, documentation updates, and CRD regeneration. The changes build upon each other progressively.

Changes

This PR addresses several goals:

  1. Configuration Consolidation: Move CRD-specific fields into config.Config to eliminate duplication and establish a single source of truth
  2. Validation Unification: Consolidate scattered validation logic into shared, reusable functions
  3. Type Simplification: Remove redundant CRD-to-config conversion functions by embedding config types directly in CRDs
  4. Bug Fixes: Fix telemetry config field loss during CRD conversion
  5. Documentation: Clarify field precedence and add proper kubebuilder annotations

Commit-by-Commit Breakdown

1. b1c52a3 - docs(vmcp): clarify IncomingAuth precedence between CRD spec and config

What: Documentation-only change

  • Clarifies that spec.IncomingAuth takes precedence over config.IncomingAuth
  • Marks config.IncomingAuth as optional since CRD field is authoritative
  • Explains that converter populates config field from CRD spec, not vice versa
  • Regenerates CRD manifests

2. d37a88f - docs(vmcp): clarify auth config precedence between CRD spec and config

What: Extends auth documentation to outgoing auth

  • Adds same precedence documentation for OutgoingAuth fields
  • Explains why CRD spec fields should be preferred (Kubernetes-native secret references)
  • Regenerates CRD manifests and documentation

3. 39f6357 - feat(operator): migrate Aggregation from VirtualMCPServerSpec to spec.config

What: Moves Aggregation field to spec.config

  • Deletes AggregationConfig, ConflictResolutionConfig, WorkloadToolConfig from CRD types
  • Adds kubebuilder annotations to config.AggregationConfig
  • Updates converter, webhook validation, controller, examples, and tests
  • BREAKING CHANGE: Must use spec.config.aggregation path
  • Regenerates CRD manifests and documentation

4. 6de62aa - refactor(operator): migrate CompositeTools and CompositeToolRefs to spec.config

What: Moves composite tool definitions to spec.config

  • Deletes CompositeToolSpec from VirtualMCPServer CRD
  • Adds CompositeToolRef type to pkg/vmcp/config for Kubernetes references
  • Changes from pointer slices to value slices ([]*T[]T)
  • Simplifies converter to pass through config fields directly
  • Updates all tests and documentation

5. 7525cc8 - refactor(operator): embed config.CompositeToolConfig in VirtualMCPCompositeToolDefinitionSpec

What: Simplifies VirtualMCPCompositeToolDefinition CRD structure

  • Embeds config.CompositeToolConfig directly instead of duplicating types
  • Removes 5 redundant conversion functions (convertCompositeToolSpec, convertWorkflowSteps, etc.)
  • Updates webhook validation to use config types directly
  • Updates all tests for new embedded structure

6. 0e5ca70 - refactor(validation): consolidate composite tool validation in pkg/vmcp/config

What: Centralizes all composite tool validation logic

  • Creates pkg/vmcp/config/composite_validation.go with shared functions
  • Moves workflow validation from scattered locations to single source of truth
  • Both CRD webhooks and config validator now use same validation code
  • Deletes redundant workflow_validation.go from v1alpha1 package
  • Adds comprehensive tests for shared validation

7. 63bbc2a - refactor(operator): migrate Operational config from spec to spec.config

What: Moves Operational field to spec.config

  • Adds LogLevel field to config.OperationalConfig
  • Adds kubebuilder annotations to timeout/failure handling/circuit breaker configs
  • Deletes 4 config types from CRD (OperationalConfig, TimeoutConfig, etc.)
  • Updates converter, controller, docs, examples, and tests
  • Regenerates CRD manifests

8. 82c92d2 - fix(telemetry): add optional annotations and defaults to telemetry.Config

What: Improves telemetry configuration ergonomics

  • Makes ServiceName, ServiceVersion, and Endpoint optional
  • Adds kubebuilder defaults:
    • TracingEnabled: false
    • MetricsEnabled: false
    • SamplingRate: "0.05"
    • Insecure: false
    • EnablePrometheusMetricsPath: false
  • Documents default behaviors for optional fields
  • Regenerates CRD manifests

9. 3b9e20d - fix(operator): preserve all telemetry config fields during CRD conversion

What: Fixes critical bug in telemetry config conversion

  • Bug: CustomAttributes, ServiceVersion, EnvironmentVariables were silently dropped
  • Root Cause: Unnecessary round-trip conversion through intermediate format
  • Solution:
    • Creates spectoconfig.NormalizeTelemetryConfig() as shared normalization logic
    • Eliminates lossy conversion path
    • Refactors both converters to use shared function
  • Testing: Adds 5 new test suites with comprehensive coverage:
    • TestConverter_TelemetryConfigPreserved - field preservation
    • TestConverter_TelemetryDefaults - default behavior
    • TestConverter_TelemetryEndpointPrefixStripping - normalization
    • TestNormalizeTelemetryConfig - 8 test cases
    • TestConvertTelemetryConfig_UsesNormalization - integration
    • New E2E test virtualmcp_telemetry_test.go

10. 49b9da0 - chore: bump operator-crds chart version to 0.0.95 and regenerate docs

What: Version bump and final regeneration

  • Bumps operator-crds chart from 0.0.94 to 0.0.95
  • Regenerates all swagger API documentation
  • Updates version badges in README

@github-actions github-actions bot added the size/XL Extra large PR: 1000+ lines changed label Jan 9, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Large PR Detected

This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.

How to unblock this PR:

Add a section to your PR description with the following format:

## Large PR Justification

[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformation

Alternative:

Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.

See our Contributing Guidelines for more details.


This review will be automatically dismissed once you add the justification section.

@jerm-dro jerm-dro force-pushed the jerm/2026-01-09-remaining-migrations branch from aab783d to aa239d9 Compare January 9, 2026 22:46
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 9, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Jan 9, 2026

Codecov Report

❌ Patch coverage is 81.26464% with 80 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.70%. Comparing base (92b08b7) to head (32f192e).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/vmcp/config/composite_validation.go 80.06% 32 Missing and 28 partials ⚠️
pkg/vmcp/config/validator.go 41.17% 9 Missing and 1 partial ⚠️
...perator/controllers/virtualmcpserver_controller.go 33.33% 6 Missing ⚠️
...lpha1/virtualmcpcompositetooldefinition_webhook.go 25.00% 3 Missing ⚠️
...-operator/api/v1alpha1/virtualmcpserver_webhook.go 96.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3242      +/-   ##
==========================================
+ Coverage   63.66%   63.70%   +0.04%     
==========================================
  Files         362      362              
  Lines       35521    35209     -312     
==========================================
- Hits        22613    22431     -182     
+ Misses      11089    10974     -115     
+ Partials     1819     1804      -15     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 10, 2026
@jerm-dro jerm-dro force-pushed the jerm/2026-01-09-remaining-migrations branch from eba9fb7 to bc234ad Compare January 10, 2026 00:48
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 10, 2026
@jerm-dro jerm-dro force-pushed the jerm/2026-01-09-remaining-migrations branch from bc234ad to 261757d Compare January 10, 2026 01:02
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 10, 2026
Add documentation clarifying the relationship between VirtualMCPServerSpec.IncomingAuth
and config.Config.IncomingAuth:

- Update spec.IncomingAuth comment to explain it takes precedence over config.IncomingAuth
  and should be preferred because it supports Kubernetes-native secret references
  (SecretKeyRef, ConfigMapRef) for secure dynamic discovery of credentials

- Mark config.IncomingAuth as optional with +optional annotation since the CRD's
  spec.IncomingAuth is the authoritative source when using the operator

- Add note to config.IncomingAuthConfig explaining that when using the Kubernetes
  operator, the converter populates this field from VirtualMCPServerSpec.IncomingAuth
  and any values set directly will be superseded

- Regenerate CRD manifests and API documentation

Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Add documentation clarifying the relationship between VirtualMCPServerSpec
auth fields and their config.Config equivalents:

- Update spec.IncomingAuth and spec.OutgoingAuth comments to explain they
  take precedence over their config counterparts and should be preferred
  because they support Kubernetes-native secret references (SecretKeyRef,
  ConfigMapRef) for secure dynamic discovery of credentials

- Mark config.IncomingAuth and config.OutgoingAuth as optional with
  +optional annotation since the CRD spec fields are the authoritative
  source when using the operator

- Add notes to config.IncomingAuthConfig and config.OutgoingAuthConfig
  explaining that when using the Kubernetes operator, the converter
  populates these fields from VirtualMCPServerSpec and any values set
  directly will be superseded

- Regenerate CRD manifests and API documentation

Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
….config

Move the Aggregation field and its associated types from the CRD spec
into the nested config.Config structure for consistency with the
platform-agnostic configuration model.

Changes:
- Delete AggregationConfig, ConflictResolutionConfig, WorkloadToolConfig
  types from api/v1alpha1 (ToolOverride kept for MCPToolConfig)
- Delete conflict resolution constants from CRD spec (use pkg/vmcp constants)
- Add kubebuilder annotations and comments to config.AggregationConfig
- Add ToolConfigRef support to config.WorkloadToolConfig for K8s references
- Update converter to copy and resolve config.Aggregation with defaults
- Update webhook validation to use vmcp.ConflictStrategy* constants
- Update controller to check vmcp.Spec.Config.Aggregation for ToolConfigRef
- Update all examples to use spec.config.aggregation path
- Update Chainsaw tests and e2e tests for new structure
- Regenerate CRD manifests and API documentation

BREAKING CHANGE: VirtualMCPServer resources must now specify aggregation
under spec.config.aggregation instead of spec.aggregation

Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
@jerm-dro jerm-dro force-pushed the jerm/2026-01-09-remaining-migrations branch from 261757d to 990efa5 Compare January 12, 2026 16:06
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 12, 2026
@jerm-dro jerm-dro force-pushed the jerm/2026-01-09-remaining-migrations branch from 990efa5 to 1252486 Compare January 12, 2026 16:27
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 12, 2026
@jerm-dro jerm-dro force-pushed the jerm/2026-01-09-remaining-migrations branch from 08a671e to e0a3752 Compare January 12, 2026 18:03
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 12, 2026
@github-actions github-actions bot added the size/XL Extra large PR: 1000+ lines changed label Jan 12, 2026
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 12, 2026
Fixed two test failures:

1. Chainsaw test (vmcp-composite-tool-definition):
   - Removed 'failureMode' field from VirtualMCPCompositeToolDefinition spec
   - Field was deleted in commit 7525cc8 when CRD was refactored to embed config.CompositeToolConfig
   - Test now passes successfully

2. Ginkgo test (virtualmcp_telemetry_test):
   - Fixed ConfigMap name from '{name}-config' to '{name}-vmcp-config'
   - Matches the actual naming convention used by vmcpConfigMapName() function
   - Test now correctly retrieves and validates telemetry configuration

Both tests verified passing with local operator deployment:
- Chainsaw vmcp-composite-tool-definition: PASS (9.03s)
- Ginkgo VirtualMCPServer Telemetry Config: PASS (27.26s)
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 13, 2026
@jerm-dro jerm-dro requested review from dmjb and jhrozek January 13, 2026 00:29
@jerm-dro jerm-dro marked this pull request as ready for review January 13, 2026 00:29
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 13, 2026
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 13, 2026
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 13, 2026
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 13, 2026
Copy link
Copy Markdown
Contributor

@jhrozek jhrozek left a comment

Choose a reason for hiding this comment

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

I only had some nits. Since this is a very large PR, feel free to ignore and merge, I'm acking

@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Jan 13, 2026
@jerm-dro jerm-dro merged commit cd114d1 into main Jan 13, 2026
44 of 45 checks passed
@jerm-dro jerm-dro deleted the jerm/2026-01-09-remaining-migrations branch January 13, 2026 21:41
ptelang pushed a commit that referenced this pull request Jan 13, 2026
This PR addresses several goals:

Configuration Consolidation: Move CRD-specific fields into config.Config to eliminate duplication and establish a single source of truth
Validation Unification: Consolidate scattered validation logic into shared, reusable functions
Type Simplification: Remove redundant CRD-to-config conversion functions by embedding config types directly in CRDs
Bug Fixes: Fix telemetry config field loss during CRD conversion
Documentation: Clarify field precedence and add proper kubebuilder annotations
---------

Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Extra large PR: 1000+ lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Simplify VMCP Configuration

2 participants