feat(): add hub-and-spoke topology fields to SliceConfig CRD - #408
feat(): add hub-and-spoke topology fields to SliceConfig CRD#408Shreesha001 wants to merge 3 commits into
Conversation
Signed-off-by: Shreesha001 <shettyshreesha552@gmail.com>
There was a problem hiding this comment.
Pull request overview
Adds Hub-and-Spoke (partial mesh MVP) API surface to the SliceConfig CRD and enforces the initial validation rules via the admission webhook, while keeping default behavior backward compatible (no spec.topology → full mesh).
Changes:
- Introduces
spec.topology(mode,hubs) in theSliceConfigGo types and CRD OpenAPI schema. - Adds create/update webhook validation for topology cross-field rules (single hub for this release, hub must be a member, etc.) with unit tests.
- Adds a Hub-and-Spoke sample
SliceConfigmanifest.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| service/slice_config_webhook_validation.go | Adds validateTopology + Hub-and-Spoke rules and wires validation into create/update paths. |
| service/slice_config_webhook_validation_test.go | Adds table-driven unit tests covering valid/invalid topology configurations. |
| config/samples/controller_v1alpha1_sliceconfig_hub_and_spoke.yaml | Adds a sample SliceConfig manifest demonstrating the new spec.topology fields. |
| config/crd/bases/controller.kubeslice.io_sliceconfigs.yaml | Extends the CRD schema with spec.topology (mode enum, hubs maxItems). |
| apis/controller/v1alpha1/zz_generated.deepcopy.go | Updates generated deepcopy functions for the new TopologySpec. |
| apis/controller/v1alpha1/sliceconfig_types.go | Adds TopologySpec / TopologyMode types and integrates them into SliceConfigSpec. |
Files not reviewed (1)
- apis/controller/v1alpha1/zz_generated.deepcopy.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| metadata: | ||
| annotations: | ||
| controller-gen.kubebuilder.io/version: v0.19.0 | ||
| controller-gen.kubebuilder.io/version: v0.17.3 | ||
| name: sliceconfigs.controller.kubeslice.io |
| # worker-1 acts as the hub; worker-2 and worker-3 become spokes (all | ||
| # non-hub members are spokes). Tunnel links are created only between | ||
| # hub and spokes: worker-1<->worker-2 and worker-1<->worker-3. | ||
| # No spoke<->spoke (worker-2<->worker-3) link is created. | ||
| # | ||
| # Omitting spec.topology entirely (or setting mode: FullMesh with no | ||
| # hubs) keeps the existing full-mesh behavior. |
gourishkb
left a comment
There was a problem hiding this comment.
Good first PR for this feature — the CRD schema, backward compatibility guarantee, and 12 table-driven tests all land well. A few things to address before merging:
Must fix
- The CRD YAML was regenerated with
controller-gen v0.17.3, but the project was onv0.19.0. This downgrades the tooling version in the committed manifest. Please regenerate withmake manifestsusing the project's canonical controller-gen version (checkgo.modorMakefile) and verify the output matches what CI produces.
Should fix
MaxItems=2in the CRD schema permits two hubs, but the webhook (len(topology.Hubs) > 1) rejects anything above one for this release. The inconsistency is intentional (CRD left permissive for future use) but needs a code comment explaining it — otherwise the next person will either tighten the CRD or remove the webhook check assuming it's a mistake.- The
spokes == 0guard at the end ofvalidateHubAndSpokeTopologyis unreachable under the current constraints: the function already requireslen(clusters) >= 2andlen(hubs) <= 1, so there is always at least one spoke. It's a good safety net for when the 2-hub limit is lifted, but should carry a comment to that effect so it isn't deleted as dead code. - Validation order in
validateHubAndSpokeTopology: the duplicate-hubs check fires before thelen > 1release restriction check. Input["cluster-1", "cluster-1"]returns"duplicate hub entry"rather than"only one hub is supported in this release". Suggest swapping the order so the release restriction (more specific) comes before the general duplicate check.
Minor
- Sample YAML is missing a trailing newline (most editors and
git diffwill flag this). - Test case
"all clusters as hubs leaves no spokes and is rejected"passes a single-element cluster list, so it actually hits the"requires at least 2 clusters"check, not the spoke check. The test passes but the name is misleading. Please rename it or add a distinct test for the no-spokes path (3 clusters, 1 hub, but... actually that path is unreachable today — see the spoke check comment above). Either add a comment in the test or rename to match what is actually being asserted. - No test exercises the update path (
ValidateSliceConfigUpdatewith a topology change, e.g.HubAndSpoke→FullMeshon an existing live slice). Is that transition intended to be allowed without any guard? Worth a test and a note in the PR body either way.
| apiVersion: apiextensions.k8s.io/v1 | ||
| kind: CustomResourceDefinition | ||
| metadata: | ||
| annotations: |
There was a problem hiding this comment.
The controller-gen version here has been downgraded from v0.19.0 to v0.17.3. This suggests make manifests was run with a different tool version than what the project uses. Please regenerate with the canonical version (go.mod / Makefile pins it) and push the corrected manifest. Committing a downgraded version can silently change CRD output for other fields.
| // Each entry must be a member of spec.clusters. All non-hub members | ||
| // become spokes. | ||
| //+optional | ||
| //+kubebuilder:validation:MaxItems=2 |
There was a problem hiding this comment.
MaxItems=2 in the CRD schema allows two hubs at the API level, but the webhook currently rejects len(hubs) > 1. This intentional inconsistency (keeping the CRD permissive for future 2-hub support) should have a comment here:
// MaxItems=2 intentionally permits 2 hubs in the CRD schema to leave room
// for future active/active hub support. The webhook currently restricts this
// to 1 hub for the MVP release.Without the comment, a future contributor will either tighten the CRD to MaxItems=1 or remove the webhook check, assuming one is wrong.
| if len(topology.Hubs) == 0 { | ||
| return field.Required(topologyPath.Child("Hubs"), "HubAndSpoke topology requires at least one hub") | ||
| } | ||
| if duplicate, value := util.CheckDuplicateInArray(topology.Hubs); duplicate { |
There was a problem hiding this comment.
These two checks are in the wrong order for clarity. len(topology.Hubs) > 1 (the current release restriction) should come before the duplicate check. As written, ["cluster-1", "cluster-1"] returns "duplicate hub entry" rather than "only one hub is supported in this release". Swap the order:
if len(topology.Hubs) > 1 {
return field.Invalid(..., "only one hub is supported in this release")
}
if duplicate, value := util.CheckDuplicateInArray(topology.Hubs); duplicate {
return field.Duplicate(...)
}| tcType: BANDWIDTH_CONTROL | ||
| bandwidthCeilingKbps: 5120 | ||
| bandwidthGuaranteedKbps: 2560 | ||
| dscpClass: AF11 No newline at end of file |
There was a problem hiding this comment.
Missing trailing newline at end of file — please add one.
| { | ||
| name: "duplicate hub entries are rejected", | ||
| clusters: clusters, | ||
| topology: &controllerv1alpha1.TopologySpec{Mode: controllerv1alpha1.TopologyModeHubAndSpoke, Hubs: []string{"cluster-1", "cluster-1"}}, |
There was a problem hiding this comment.
Test name "all clusters as hubs leaves no spokes and is rejected" is misleading — clusters here is ["cluster-1"] (single item), so it hits the "requires at least 2 clusters" check first, not the spoke check. Please rename to "single-cluster HubAndSpoke is rejected (needs at least 2 clusters)" to match what is actually being asserted.
- pin Hubs to MaxItems=1 (schema now matches the single-hub webhook rule) - order the single-hub check before the duplicate check; mark both as defense-in-depth behind the schema limit - comment the unreachable spokes==0 guard - clarify the sample is API/validation-only (topology not yet consumed) - add trailing newline to sample; regen CRD with controller-gen v0.19.0 Signed-off-by: Shreesha001 <shettyshreesha552@gmail.com>
…gy test cases Signed-off-by: Shreesha001 <shettyshreesha552@gmail.com>
Adds the API for Hub-and-Spoke topology (Partial Mesh MVP), per the ADR (#300).
spec.topologyfield on SliceConfig:mode(FullMesh|HubAndSpoke) andhubs. All non-hub clusters are spokes automatically.topologyfield → existing full-mesh behavior, unchanged.Fixes #301
How Has This Been Tested?
topologyunaffected.Checklist:
Does this PR introduce a breaking change for other components like worker-operator?
No