Skip to content

OSAC-1382: Design - Multi-Fabric East-West Networking - #179

Merged
openshift-merge-bot[bot] merged 9 commits into
osac-project:mainfrom
vladikr:design/OSAC-1382
Aug 27, 2026
Merged

openshift-merge-bot[bot] merged 9 commits into
osac-project:mainfrom
vladikr:design/OSAC-1382

Conversation

@vladikr

@vladikr vladikr commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Design: Multi-Fabric East-West Networking

Jira: OSAC-1382
PRD: prd.md (merged in PR #117)

Summary

Introduces FabricDomain as a first-class OSAC resource for east-west fabric isolation, separate from VirtualNetwork (which remains the north-south / IP isolation boundary). Phase 1 delivers Ethernet east-west
via Netris Server Clusters.

Each FabricDomain requires exactly one VirtualNetwork in Phase 1 — the Server Cluster is created in that VN's Netris VPC. Backend config (template_id) lives on NetworkClass, not on the domain object.

Core operational risk retired: VPC-first → Server Cluster in existing VPC → OSAC Subnet coexistence and tenant isolation validated on zeus12 netris-lab.

Key Design Decisions

  • Two isolation planes: N-S (VirtualNetwork) and E-W (FabricDomain) — IP isolation alone does not isolate the GPU fabric
  • FabricDomain with condition-based lifecycle (not phase enum)
  • NetworkClassCapabilities.supports_east_west_ethernet gates validation
  • Phase 1: exactly one VN required per FabricDomain (1:1)
  • Phase 2/3: IB/NVLink types reserved in API; type: multi planned for uniform deployments
  • AAP layer already implemented (osac-aap PR #447)
  • NVIDIA DGX SuperPOD and NICo references support non-uniform fabric membership

Validation

  • VPC-first → Server Cluster in existing VPC → OSAC Subnet coexistence validated on zeus12 netris-lab — no VNet/VXLAN conflicts.
  • Tenant isolation verified: same-tenant traffic flows, cross-tenant blocked on both EW and NS paths.

@openshift-ci-robot

openshift-ci-robot commented Aug 1, 2026 •

Copy link
Copy Markdown

@vladikr: This pull request references OSAC-1382 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the feature to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Design: Multi-Fabric East-West Networking

Jira: OSAC-1382
PRD: prd.md (merged in PR #117)

Summary

Extends VirtualNetwork with a fabric_bindings field for declarative east-west connectivity. Each binding type maps to a NetworkClass capability and triggers a separate AAP job during reconciliation. Phase 1 delivers Ethernet east-west via Netris Server Clusters (L3VPN isolation). No new resource types introduced.

Core operational risk retired: VPC-first → Server Cluster in existing VPC → OSAC Subnet coexistence validated on zeus12 netris-lab. All VNets coexist with unique VXLAN IDs, no conflicts.

Key Design Decisions

  • fabric_bindings on VirtualNetwork (not a new EastWestDomain resource)
  • NetworkClassCapabilities.supports_east_west_ethernet gates binding validation
  • Two-phase operator reconciliation: standard VPC first, then per-binding AAP jobs
  • Aligns with future dispatcher (OSAC-1457): dispatcher reads fabric_bindings and dispatches to fabric managers
  • Phase 2/3 add new binding types (infiniband_ew, nvlink) — same field, new values
  • AAP layer already implemented (osac-aap PR #447)

Requesting Review On

  • fabric_bindings as the extension point — is VirtualNetwork the right place for this, vs a separate resource or Subnet-level binding?
  • Resize semantics — template_id is immutable per binding; servers list is mutable. Is this the right policy?
  • Phase 1 limitations — no server eligibility validation, Netris-specific template_id, no auto-assignment from pool
  • Virtual cluster support — Phase 1 targets bare metal only; VMs need SR-IOV (sketched as future ethernet_ew_sriov binding type)
  • Multi-binding alignment (Phase 2+) — multiple binding types share a VPC; cross-binding server alignment is admin-enforced in Phase 1

How to Review

  • Comment inline on specific sections
  • Approve when the design accurately reflects a viable implementation approach

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added the approved label Aug 1, 2026
@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 44f586d9-4589-4001-a699-8f67aa147a1c

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The design introduces an independent, tenant-scoped FabricDomain resource for Ethernet east-west networking. It defines service and CRD contracts, Netris provisioning through AAP, controller reconciliation, validation, lifecycle operations, recovery, testing, and rollout procedures.

Changes

FabricDomain east-west networking

Layer / File(s) Summary
FabricDomain contracts and validation
enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md
Defines FabricDomain service and CRD types, lifecycle states, CRUD and Signal operations, Ethernet template configuration, NetworkClass capabilities, and validation rules.
Lifecycle and provisioning orchestration
enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md
Defines creation, VirtualNetwork association, resizing, deletion, NetworkClass resolution, AAP provisioning, controller feedback, persistence, and independent lifecycles.
Fabric scope and operational controls
enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md
Documents Ethernet prerequisites, Netris and AAP contracts, tenant isolation, authorization controls, failure recovery, idempotency, metrics, and events.
Validation and rollout
enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md
Specifies rejected alternatives, test coverage, staged graduation, version-skew behavior, compatibility procedures, recovery support, and infrastructure requirements.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Admin
  participant FulfillmentService
  participant OperatorController
  participant AAP
  participant Netris
  Admin->>FulfillmentService: Create FabricDomain
  FulfillmentService->>OperatorController: Reconcile FabricDomain
  OperatorController->>AAP: Start provisioning
  AAP->>Netris: Create or update Server Cluster
  Netris-->>AAP: Return provisioning status
  AAP-->>OperatorController: Report status
  OperatorController-->>FulfillmentService: Persist FabricDomain status
Loading

Possibly related PRs

Suggested reviewers: eliorerz, rawagner, alonakaplan

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed The commit adds only design.md; scans found no API keys, tokens, passwords, private keys, embedded-credential URLs, vendor credential formats, or credential-named literal assignments.
No-Weak-Crypto ✅ Passed The PR adds only design documentation; exact searches of added lines found no MD5, SHA-1, DES, 3DES, RC4, Blowfish, ECB, or custom crypto/comparison logic.
No-Injection-Vectors ✅ Passed The PR only adds a design document; review found no SQL concatenation, shell=True, eval/exec, pickle.loads, unsafe YAML loading, os.system, or dangerouslySetInnerHTML.
Container-Privileges ✅ Passed The PR adds only a Markdown design document; it contains no container or Kubernetes manifests and no flagged privilege settings.
No-Sensitive-Data-In-Logs ✅ Passed The PR adds only design.md; it contains no logging implementation or log payloads. It mentions AAP logs but adds no passwords, tokens, API keys, PII, or customer data to logs.
Ai-Attribution ✅ Passed The sole PR commit includes Assisted-by: Claude Code <noreply@anthropic.com> and has no Co-Authored-By trailer.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the design proposal for Multi-Fabric East-West Networking and matches the primary changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

AI Design Review: EP-179

Score: 6/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Deep technical detail throughout. Full proto schemas with field types for FabricBinding, FabricBindingStatus, FabricBindingPhase enum. CRD Go structs provided. Validation rules enumerated (VN-VAL-13/14/15, NC-VAL-09). All lifecycle operations covered: create (workflow + sequence diagram), update/resize (semantics table with 4 change types), delete (reverse-order). Failure handling table covers 5 specific failure modes with user-observable symptoms and recovery. Risks are concrete with specific m
Testability 1/2 Test plan is strong with concrete scenarios at all three levels: 8 specific unit tests (validation rules, reconciler behaviors, resize, deletion order), 4 integration tests (NC storage, CR creation, re-provisioning, reverse-order cleanup), 3 E2E tests (full lifecycle on netris-lab, VNet coexistence scenario, error path). However, graduation criteria are vague: 'Dev Preview to Tech Preview to GA based on production deployment feedback' provides no measurable conditions for stage transitions — e.g
Scope 1/2 Boundaries mostly clear with good PRD reference (frontmatter + inline link). Non-goals are specific with phase/ticket references (InfiniBand Phase 2, NVLink Phase 3, pool-based assignment, namespace isolation EP #107). Four real alternatives with pros/cons/rejection rationale. However, two cross-cutting dimensions from osac-dimensions.md are not addressed: (1) Installation — CRD extensions require osac-installer updates per AGENTS.md deployment coordination rules, but no mention of Helm/Kustomiz
Architecture 2/2 All OSAC patterns followed: tenant isolation inherited via existing VN metadata.tenant + OPA policies, spec/status separation correct (fabric_bindings in spec, fabric_binding_statuses in status), proto uses standard enum with UNSPECIFIED default, repeated list not map, controller extends existing reconciler with RunProvisioningLifecycle. Cross-repo impacts clearly enumerated (fulfillment-service proto, osac-operator CRD+controller, osac-aap role rename). Minor issue: proto FabricBindingStatus (p

Verdict: A technically strong design that extends VirtualNetwork with fabric bindings using sound OSAC patterns and deep implementation detail, but lacks coverage of the Installation and Documentation dimensions and has vague graduation criteria.

Feedback: Two actionable improvements would strengthen this design: (1) Add an Installation section addressing osac-installer changes — the new CRD fields (fabricBindings on VirtualNetwork) must flow through Helm charts/Kustomize overlays, and per AGENTS.md, failing to update osac-installer after cross-component changes causes CI failures. (2) Replace the graduation criteria with measurable conditions (e.g., 'Tech Preview: all CRUD operations pass E2E on netris-lab, error paths tested, VNet coexistence validated; GA: production deployment with N tenants, no regressions in existing networking tests'). Also align the proto FabricBindingStatus fields with the CRD Go struct — the ProvisioningJobs field appears in the CRD but not the proto, and the message field is in the proto but not the CRD.

Critical (0)

None.

Important (5)

  1. Installation dimension not addressed: CRD extensions (fabricBindings on VirtualNetworkSpec) require osac-installer updates (Helm charts, Kustomize overlays). AGENTS.md warns: 'Failing to update osac-installer after cross-component changes causes CI failures and deployment mismatches.' Add an Installation section specifying what changes are needed.
  2. Documentation dimension not addressed: No mention of user-facing docs needed. At minimum: admin workflow guide for creating VNs with fabric bindings, updated API reference for new proto fields, and NetworkClass configuration guide for supports_east_west_ethernet capability.
  3. Graduation criteria are vague: 'Dev Preview → Tech Preview → GA based on production deployment feedback' lacks measurable conditions. Define concrete criteria for each stage (e.g., CRUD pass rates, error path coverage, performance benchmarks, production tenant count).
  4. Proto/CRD field mismatch: Proto FabricBindingStatus has fields (phase, message, backend_id) but the CRD Go struct has (Phase, ProvisioningJobs, BackendID). ProvisioningJobs []JobStatus doesn't appear in proto; message from proto doesn't appear in CRD. These must be aligned before implementation.
  5. Personas not explicitly named in workflow: The workflow description uses 'Admin' generically. Should specify which OSAC persona (Cloud Infrastructure Admin for NetworkClass setup, Cloud Provider Admin for VN creation with bindings) performs each action, per osac-dimensions.md persona definitions.

Suggestions (3)

  1. Add a Terminology section defining key terms (isolation domain, Server Cluster, fabric manager, VPC, binding type) upfront — the Networking EP (reference library) sets this precedent and reviewers expect it.
  2. Specify gRPC error codes for validation failures: e.g., VN-VAL-13 → INVALID_ARGUMENT with message naming the unsupported binding type and NetworkClass.
  3. Explicitly defer UI dimension: Add 'UI: deferred to Phase 2. Fabric bindings are managed via CLI/API only in Phase 1' rather than leaving it implicit from the UX Alignment N/A statement.

Review cost

Model: claude-opus-4-6
Cost: $0.7453
Tokens: 8 in / 6.9k out
Cache: 292.7k read
Active time: 2m 49s
API calls: 0

@github-actions github-actions Bot added the rfe-creator-auto-reviewed EP was reviewed by AI label Aug 1, 2026

@danmanor danmanor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Design review — four questions about extensibility and scope beyond Phase 1.

// Fabric-manager-specific template identifier.
string template_id = 3;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is fabric_bindings on VirtualNetwork instead of Subnet?

In OSAC's model, servers attach to Subnets (via network_attachments), not directly to VirtualNetworks. A tenant may have one VN with multiple Subnets where only some need east/west connectivity:

VirtualNetwork "my-vn" (10.0.0.0/16)
  ├── Subnet "gpu-training"  (10.0.1.0/24)  ← needs east/west
  ├── Subnet "web-services"  (10.0.2.0/24)  ← does NOT need east/west
  └── Subnet "storage"       (10.0.3.0/24)  ← different east/west need

With bindings at the VN level, you can't scope east/west to a specific Subnet — the servers list is the only scoping mechanism, but it's not tied to which Subnet those servers are in.

I understand this maps to how Netris Server Clusters work today (scoped to a VPC). But is this the right abstraction level for Phase 2+ when different Subnets may need different fabric treatment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You are right, and that's tricky. I thought to go with a simple model first and then creating a separate resource.
Regarding subnets... I agree that going forward we need a separation, but Subnets themselves are just addresses inside an isolation domain, right? So there can be multiple attached to one isolation domain.
In terms of ownership, I didn't think that a deletion of a subnet should lead to the destruction of an isolation domain...

repeated FabricBindingStatus fabric_binding_statuses = 4;
}

message FabricBindingStatus {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How will the tenant know what template_id to use?

This is a raw Netris Server Cluster Template ID. The tenant has no way to discover available templates or understand what they mean. Even for admin-only Phase 1, this creates a dependency on out-of-band knowledge of the Netris Controller's inventory.

Should this be derived from the NetworkClass configuration instead? The admin could configure the template once on the NetworkClass ("when ethernet_ew is requested, use template X"), and the fulfillment-service would resolve it automatically — similar to how implementationStrategy is resolved from NetworkClass today. That would also make default_fabric_bindings cleaner (no need to repeat template_id in defaults).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, I agree. You're right, it's in the wrong place and should be in the NetworkClass :/
I'll rework that.

When InfiniBand and NVLink bindings are introduced, this is insufficient. IB requires servers with HCAs visible to UFM; NVLink requires GPUs in the correct NVLink domain (NVL72/NVL144). Handing a server list with missing hardware to UFM or NMX results in either silent partial failures or active domains with only a subset of requested servers — unacceptable for expensive GPU infrastructure.

The validation model for Phase 2+:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this generic enough to work with a non-Netris fabric manager?

The type and servers fields are fabric-manager-agnostic, but template_id leaks Netris semantics. For other fabric managers:

Fabric Manager What template_id maps to Needed?
Netris Server Cluster Template ID Yes
UFM (InfiniBand) Nothing — P_Key partitions don't use templates No
Neutron Network profile? Maybe

Would a map<string, string> parameters field (or deriving config from NetworkClass) be more future-proof than a Netris-specific template_id? The Fabric Manager Capability Contract section defines a generic interface, but the proto shape doesn't fully match that genericity.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

+1 yes.

| Partial binding success (A ok, B fail) | VN Failed; A shows Ready, B shows Failed | Fix B; A is not re-provisioned |
| Delete binding job fails | VN stuck in Deleting | Manually delete from fabric manager, remove finalizer |

All AAP jobs are idempotent.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How does this model fit separate east/west use cases like storage?

A GPU server often has three distinct fabrics: north/south Ethernet, east/west GPU (IB or RoCE), and east/west storage (NVMe-oF). GPU and storage east/west are different isolation domains on different physical networks with potentially different tenancy boundaries.

With bindings on VN, you'd model this as:

fabric_bindings:
  - type: "ethernet_ew"   # GPU
    servers: ["hgx-00"]
  - type: "storage_ew"     # Storage
    servers: ["hgx-00"]

This forces both to share the same VN lifecycle — you can't independently manage the storage domain without touching the GPU VN, and different teams can't own them separately. A standalone resource (like Nebius's GpuCluster or Crusoe's ib-partition) would decouple these lifecycles.

Is this an acceptable trade-off for Phase 1, or should the design acknowledge this as a known limitation that may require factoring out a dedicated resource in Phase 2+?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yes, I don't think it's enough for phase 2+, I was just worried that no matter what we'll design now may not 100% fit..
I was debating with myself whether we should introduce a separate EastWestDomain resource now or do phase 1 and then.
Let me think about this again and see if I can propose a different approach.

@vladikr
vladikr marked this pull request as ready for review August 3, 2026 10:51
@openshift-ci
openshift-ci Bot requested review from eliorerz and rawagner August 3, 2026 10:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md`:
- Around line 122-132: Update FabricBinding admission validation and the
corresponding CRD schema so ethernet_ew requires a valid Netris Server Cluster
template_id, rejects missing or invalid values, and enforces immutability after
creation. Apply the same validation to the referenced FabricBinding definitions
and add tests covering missing, invalid, and changed template_id values.
- Around line 134-154: Align the VirtualNetworkStatus and CRD binding-status
contracts by defining one canonical binding status model and an explicit
conversion between the proto FabricBindingStatus and CRD status fields.
Reconcile type, phase, message, backend ID, and provisioningJobs so no status
information is silently lost, constrain phase values to the shared lifecycle,
and add a DELETING phase or explicitly define when binding status is removed.
- Around line 215-242: Extend the VirtualNetwork status model and provisioning
flow around ComputeDesiredConfigVersion to persist each fabric binding’s
last-applied configuration hash keyed by a stable binding identity. Use this
durable per-binding state to selectively detect updates across reconciles and
restarts, while correctly handling server changes, additions, removals, and
reordered bindings without treating unchanged bindings as modified.
- Around line 157-170: Define supports_east_west_ethernet as a derived
capability on NetworkClass, inferred from assigned fabric-manager metadata and
published through status.capabilities rather than relying on the Pydantic
default or manual values. Apply the existing disableCapabilities behavior during
derivation, and update VN validation to consume the published derived
capability. Align the implementation with the established unified-networking
capability flow.
- Around line 261-267: Update the fenced code block containing the VPC and
server-cluster API sequence to specify the text language, using ```text as the
opening fence while preserving the existing sequence unchanged.
- Around line 52-56: Make the supports_east_west_ethernet capability rename
backward-compatible by retaining supports_east_west as a deprecated alias or
adding an explicit migration across AAP metadata, the operator, and
fulfillment-service. Add mixed-version coverage for old and new capability keys,
and document the required upgrade order for AAP, operator, and
fulfillment-service independently of the fabricBindings skew strategy.
- Around line 293-297: Update the fabric_bindings authorization design to
require admin-only access for both servers and template_id on API and CRD paths,
rather than relying on VirtualNetwork tenant/OPA scoping. Add validation against
authoritative inventory to confirm selected servers are owned or assigned
appropriately before provisioning.
- Around line 94-96: Update the Tenant Onboarding via NetworkDefaults design so
default_fabric_bindings cannot reuse concrete provider-level servers across
tenants. Define a tenant-scoped binding profile with per-tenant server
resolution, or explicitly disable automatic defaults until tenant-scoped
allocation exists, and document an explicit opt-out path when defaults are
configured.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c70f6ae0-c765-423c-8550-91e7288ec286

📥 Commits

Reviewing files that changed from the base of the PR and between 9fab7b7 and d69d7de.

📒 Files selected for processing (1)
  • enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md

Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment on lines +134 to +154
message VirtualNetworkStatus {
// ... existing fields 1-3 ...

// Per-binding provisioning status.
repeated FabricBindingStatus fabric_binding_statuses = 4;
}

message FabricBindingStatus {
string type = 1;
FabricBindingPhase phase = 2;
optional string message = 3;
string backend_id = 4;
}

enum FabricBindingPhase {
FABRIC_BINDING_PHASE_UNSPECIFIED = 0;
FABRIC_BINDING_PHASE_PENDING = 1;
FABRIC_BINDING_PHASE_PROVISIONING = 2;
FABRIC_BINDING_PHASE_READY = 3;
FABRIC_BINDING_PHASE_FAILED = 4;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Align the proto and CRD binding-status contracts.

The proto status contains type, enum phase, message, and backend_id. The CRD status contains type, string phase, provisioningJobs, and backendId. No conversion is defined.

provisioningJobs cannot be represented by the proto. message cannot be represented by the CRD. The free-form CRD phase can diverge from the proto enum. The proto enum also lacks DELETING, although deletion is a supported lifecycle.

Define one canonical status model and an explicit conversion. Add a deletion phase or document when binding status is removed.

Also applies to: 187-197

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 134 - 154, Align the VirtualNetworkStatus and CRD binding-status contracts
by defining one canonical binding status model and an explicit conversion
between the proto FabricBindingStatus and CRD status fields. Reconcile type,
phase, message, backend ID, and provisioningJobs so no status information is
silently lost, constrain phase values to the shared lifecycle, and add a
DELETING phase or explicitly define when binding status is removed.

Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment on lines +215 to +242
#### Operator Two-Phase Provisioning

The `VirtualNetworkReconciler.handleProvisioning` is extended:

**Phase 1 (existing):** Standard VN provisioning fires `osac-create-virtual-network` (creates VPC). Tracked via `status.provisioningJobs`.

**Phase 2 (new):** For each `spec.fabricBindings` entry, the operator looks up the binding type in a constant map:

```go
var fabricBindingTemplates = map[string]struct {
createTemplate string
deleteTemplate string
}{
"ethernet_ew": {
createTemplate: "osac-create-server-cluster",
deleteTemplate: "osac-delete-server-cluster",
},
}
```

It constructs a server_cluster payload from the VN metadata + binding fields and fires the AAP job using a dedicated `AAPProvider` with explicit template names. Each binding's job is tracked independently in `fabricBindingStatuses`.

VN Phase = Ready only when ALL jobs (standard + all bindings) succeed.

#### Spec Change Detection (Resize)

`fabric_bindings` is included in the spec hash computed by `ComputeDesiredConfigVersion`. When an admin updates `fabricBindings[0].servers`, the hash changes, and the operator re-triggers provisioning for the changed binding only.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Persist per-binding desired state for selective resize.

ComputeDesiredConfigVersion is a whole-VN hash. The status model has no per-binding configuration hash or stable binding identity. After changing one of multiple bindings, or after a controller restart, the operator cannot determine which binding changed from this contract.

Store the last-applied hash keyed by binding identity, or define an equivalent durable comparison mechanism. Test server updates, additions, removals, and list reordering.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 215 - 242, Extend the VirtualNetwork status model and provisioning flow
around ComputeDesiredConfigVersion to persist each fabric binding’s last-applied
configuration hash keyed by a stable binding identity. Use this durable
per-binding state to selectively detect updates across reconciles and restarts,
while correctly handling server changes, additions, removals, and reordered
bindings without treating unchanged bindings as modified.

Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment on lines +293 to +297
#### Phase 1 Limitations

- **No server eligibility validation.** The admin is trusted to specify servers that have the correct NICs for the fabric binding. There is no check against HostType interfaces or Netris inventory. If servers lack the required NICs, the Server Cluster activates but VNet ports remain inactive.
- **Server list membership is not restricted** beyond existing VirtualNetwork tenancy. The admin is trusted to supply correct hostnames for the binding type.
- **`template_id` is Netris-specific.** It references a Netris Server Cluster Template by ID. Future phases will replace this with a more abstract profile or capability selector once multiple fabric managers are supported.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 5 \
  'fabricBindings|fabric_bindings|templateId|template_id|osac.openshift.io/tenant|Role|ClusterRole|OPA' \
  --glob '*.go' \
  --glob '*.yaml' \
  --glob '*.yml' \
  --glob '*.proto'

Repository: osac-project/enhancement-proposals

Length of output: 172


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | sed -n '1,200p'

echo "== design file snippet =="
if [ -f enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md ]; then
  wc -l enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md
  sed -n '240,410p' enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md | nl -ba -v240
fi

echo "== related searches =="
rg -n -C 3 \
  'fabricBindings|fabric_bindings|templateId|template_id|PhysicalServer|HostType|Netris|Netris inventory|virtualnetwork|VirtualNetwork|tenancy|admin-only|admin|RBAC|OPA|Role|ClusterRole|validate|authorization|tenant' \
  . || true

Repository: osac-project/enhancement-proposals

Length of output: 4599


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== git status/stat =="
git status --short
git diff --stat || true

echo "== tracked design files =="
git ls-files | grep -F 'enhancements/OSAC-1382-multi-fabric-east-west-networking' || true

Repository: osac-project/enhancement-proposals

Length of output: 352


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== design.md relevant sections =="
sed -n '280,390p' enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md

echo "== prd.md relevant searches =="
rg -n -C 4 \
  'fabricBindings|fabric_bindings|templateId|template_id|PhysicalServer|Netris|VirtualNetwork|tenant|admin|authorization|RBAC|OPA|role|cluster role|permissions|servers' \
  enhancements/OSAC-1382-multi-fabric-east-west-networking/prd.md || true

echo "== design.md mentions =="
rg -n -C 4 \
  'fabricBindings|fabric_bindings|templateId|template_id|PhysicalServer|Netris|VirtualNetwork|tenant|admin|authorization|RBAC|OPA|role|cluster role|permissions|servers' \
  enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md || true

Repository: osac-project/enhancement-proposals

Length of output: 41328


Enforce authorization for servers and template_id.

fabric_bindings is proposed as admin-only, but the RBAC section says the field only inherits VirtualNetwork tenant/OPA scoping. Tenant scoping does not authorize selecting physical server inventory or Netris templates. Add explicit admin-only authorization on both API and CRD paths, and validate server ownership/assignment against authoritative inventory before provisioning.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 293 - 297, Update the fabric_bindings authorization design to require
admin-only access for both servers and template_id on API and CRD paths, rather
than relying on VirtualNetwork tenant/OPA scoping. Add validation against
authoritative inventory to confirm selected servers are owned or assigned
appropriately before provisioning.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

AI Design Review: EP-179

Score: 5/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Strong technical detail throughout. Proto schemas are complete with field types, validation rules are enumerated (FD-VAL-01 through FD-VAL-07, NC-VAL-09), all lifecycle operations covered (create, resize, delete with explicit semantics table), failure modes described with user-observable symptoms and recovery actions, and risks cite specific technical concerns (activation latency ~60-70s, fabric manager API changes) with concrete mitigations. Zeus12 validation adds credibility. Drawbacks section
Testability 1/2 Test plan covers unit, integration, and E2E levels with some good specifics — unit tests enumerate specific validation rules and reconciler callbacks, E2E describes a concrete full-lifecycle scenario on netris-lab including VNet coexistence and error paths. However, integration test section is thin (3 bullet points, no mention of test infrastructure like kind cluster or mocked backends). Graduation criteria are just stage names ('Dev Preview → Tech Preview → GA') without measurable conditions fo
Scope 1/2 Clear Phase 1 boundaries with specific non-goals referencing future phases. Four real alternatives with rejection rationale. PRD referenced in frontmatter. However, goals read as engineering tasks ('Introduce FabricDomain as a new standalone resource', 'Extend NetworkClassCapabilities') rather than user-visible outcomes. Several relevant cross-cutting dimensions from osac-dimensions.md are not addressed: Installation (does osac-installer need Helm chart changes for the new CRD/config-as-code?),
Architecture 1/2 Core OSAC patterns followed: standard object shape (id, Metadata, Spec, Status), tenant isolation via osac.openshift.io/tenant + OPA, RunProvisioningLifecycle reuse, dual-controller pattern, NetworkClass pluggable architecture. Three issues: (1) implementation_strategy in FabricDomainSpec is described as 'derived from NetworkClass at creation time' — this is system-derived data that belongs in status or an internal field, not in spec which should contain only user-desired state; (2) a Phase enum

Verdict: The design is technically sound and follows established OSAC patterns with strong feasibility, but scores are pulled down by spec/status ownership violations, a phase enum on a new resource (should prefer conditions), thin integration test details, vague graduation criteria, and unaddressed cross-cutting dimensions (Installation, Documentation, UI deferral).

Feedback: Three concrete improvements to strengthen this design: (1) Move implementation_strategy out of FabricDomainSpec into status or an internal field — spec must contain only user-desired state, and this field is system-derived from NetworkClass at creation time. Similarly, prefer conditions over the FabricDomainState phase enum for this new resource per OSAC conventions. (2) Flesh out the integration test section with test infrastructure details (kind cluster? mocked fabric manager?) and replace the graduation criteria placeholder ('Dev Preview → Tech Preview → GA') with measurable conditions (e.g., 'all CRUD e2e pass on netris-lab, no regressions in existing networking tests, error paths validated'). (3) Address the Installation, Documentation, and UI cross-cutting dimensions — even a one-line 'deferred to Phase 2' is better than silence, which reviewers will flag as a gap.

Critical (0)

None.

Important (6)

  1. implementation_strategy in FabricDomainSpec is system-derived ('derived from NetworkClass at creation time') — violates spec/status ownership. Spec must contain only user-desired state. Move to status or treat as an internal-only field not exposed in the user-facing API.
  2. FabricDomainState phase enum introduced for a new resource. OSAC architecture checklist says 'Conditions used for lifecycle state (preferred over phase enums for new resources)'. The CRD already has a Conditions field — use it as the primary lifecycle mechanism and consider dropping the phase enum.
  3. Graduation criteria are just stage names ('Dev Preview → Tech Preview → GA') with no measurable conditions. Specify what must be true to move between stages (e.g., 'All CRUD operations pass e2e, error paths tested, no regressions in existing networking tests').
  4. Integration test section lacks infrastructure details — doesn't specify whether tests use a kind cluster, mocked fabric manager, or live backend. Compare with calibration example T=2 which specifies 'integration tests for subnet creation and attachment using kind cluster with mock network backend'.
  5. Installation dimension not addressed: does osac-installer need Helm chart changes for the new FabricDomain CRD, config-as-code entries, or RBAC? Silence on a relevant dimension is a gap per osac-dimensions.md.
  6. Documentation and UI dimensions not addressed or explicitly deferred. The UX Alignment section notes no temp-api file, but the UI dimension asks whether UI is in scope or deferred — state this explicitly. Documentation plans (API reference, admin guide for FabricDomain management) are absent.

Suggestions (4)

  1. Add a Terminology section defining key terms: FabricDomain, east-west (in OSAC context), Server Cluster (Netris-specific concept), VPC (Netris VPC vs general concept). The merged networking EP uses a Terminology section as a notable pattern.
  2. Clarify the many-to-many FabricDomain-to-VirtualNetwork lifecycle interaction: what happens when a VN referenced by a FabricDomain is deleted? Is there a finalizer or validation preventing it? The reverse case (FD deleted while VN references it) is covered but the forward case is not.
  3. Goals should be reframed as user-visible outcomes rather than engineering tasks. For example: 'Enable admins to create fabric-level east-west isolation domains for tenant server groups with full lifecycle management' instead of 'Introduce FabricDomain as a new standalone resource with full CRUD lifecycle'.
  4. Consider explicitly stating whether FabricDomain servers should integrate with OSAC inventory backends in Phase 2+, since the Inventory dimension is relevant (admin currently provides hostnames manually with no validation).

Review cost

Model: claude-opus-4-6
Cost: $0.4825
Tokens: 7 in / 5.2k out
Cache: 250.0k read
Active time: 2m 5s
API calls: 0

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md`:
- Around line 89-91: Define the VPC cardinality and ownership rules for
FabricDomain.virtual_networks: specify behavior for zero associations,
deterministic mapping for multiple associations, and ownership of the single VPC
recorded in status.vpc_id. Update the “With VirtualNetwork Association” design
and related sections to enforce one VN or explicitly model per-VN resources, and
add coverage for zero, one, multiple, and removed associations.
- Around line 227-237: Define the resolved template transport field in
FabricDomainSpec and carry it consistently through the proto, CRD, and AAP
payload mapping. Keep it write-protected from user configuration, populate it
from NetworkClass during fulfillment, and update
playbook_osac_create_fabric_domain.yml to consume the declared field when
invoking create_server_cluster.
- Around line 288-293: Update the code fence containing the Netris API workflow
near the POST /api/v2/vpc and POST /api/v2/server-cluster lines to specify the
text language, changing the opening fence to ```text while preserving the block
contents.
- Around line 101-103: Define the canonical
NetworkDefaults.default_fabric_domains schema and document how each entry
expands into a tenant-scoped FabricDomainSpec, including required servers,
networkClass, and tenant-scoped virtualNetworks. Ensure the OSAC-2341 onboarding
path can populate all required fields before describing automatic FabricDomain
creation as supported.
- Around line 93-99: Update the Resize and Deletion sections to define the AAP
idempotency key as a stable value derived from the immutable FabricDomain
identity and tenant, and specify that FabricDomainStatus.backend_id is persisted
and reused across retries. Document retry-after-success behavior, ensure renames
do not change the key or target existing cluster, and state how the persisted
backend_id is handled during deletion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 708ee7e4-2926-4e37-af47-5c60af0b396d

📥 Commits

Reviewing files that changed from the base of the PR and between d69d7de and d6d3a03.

📒 Files selected for processing (1)
  • enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md

Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
@vladikr
vladikr force-pushed the design/OSAC-1382 branch 2 times, most recently from 53aec02 to a22e7ff Compare August 3, 2026 17:40
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

AI Design Review: EP-179

Score: 5/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Proto schemas present with field types for FabricDomain and NetworkClass extensions. All lifecycle operations (create, resize, delete) described with sequence diagram. Validation rules enumerated (FD-VAL-01 through FD-VAL-07, NC-VAL-09). Failure handling table with recovery paths. Risks are specific with concrete mitigations. Drawbacks section steel-mans the argument. Minor gap: no gRPC error codes specified for validation failures.
Testability 1/2 Unit tests are specific (validation rules, template_id resolution, reconciler callbacks). E2E tests describe concrete scenarios (full lifecycle on netris-lab, VNet coexistence, error paths). Integration tests present but thin — just three bullets with no test infrastructure detail (kind cluster config, mock backends). Graduation criteria are just stage names ('Dev Preview → Tech Preview → GA') with no measurable conditions — the rubric requires concrete conditions, not milestone labels.
Scope 1/2 Summary is well-sized (4 sentences). Non-goals are specific with phase assignments and cross-references (InfiniBand Phase 2, NVLink Phase 3, pool-based assignment, EP #107). Alternatives section is excellent — four real alternatives with detailed rejection rationale. PRD referenced in frontmatter. Gaps: Installation dimension not addressed (new CRD deployment, Helm chart changes for osac-installer). Documentation dimension not addressed. Inventory dimension arguably relevant (server list validat
Architecture 1/2 Standard object shape followed (id, Metadata, Spec, Status). Tenant isolation via osac.openshift.io/tenant annotation and OPA policies described. Controller follows RunProvisioningLifecycle pattern. NetworkClass pluggability correctly used. However: (1) FabricDomainState phase enum used as primary lifecycle indicator instead of conditions, which the rubric prefers for new resources. (2) implementation_strategy in Spec is 'derived from NetworkClass at creation time' — system-derived data belongs

Verdict: The design is a solid, pattern-following enhancement proposal that passes on the strength of its detailed proto schemas, concrete validation rules, specific risk mitigations, and thorough alternatives analysis, but is held back by spec/status ownership issues, missing conditions-based lifecycle, thin graduation criteria, and unaddressed cross-cutting dimensions (Installation, Documentation).

Feedback: Three high-impact improvements: (1) Move implementation_strategy from Spec to Status and use Conditions (not a phase enum) as the primary lifecycle indicator for this new resource — this aligns with the stated preference for conditions on new resources and fixes the spec/status ownership issue. (2) Add measurable graduation criteria (e.g., 'all CRUD operations pass e2e with <2% flake rate, error paths tested, no regressions in existing networking tests') instead of bare stage names. (3) Address the Installation dimension — specify what Helm chart changes osac-installer needs for the new FabricDomain CRD, and add a Terminology section defining 'Server Cluster', 'VPC', and 'east-west' upfront to prevent reviewer confusion.

Critical (0)

None.

Important (5)

  1. FabricDomainState phase enum used as primary lifecycle indicator instead of conditions. The architecture rubric prefers conditions for new resources. The CRD includes Conditions but Phase is the primary state tracker (proto: FabricDomainState with PENDING/READY/FAILED; CRD: FabricDomainPhaseType). Existing resources use phase for historical reasons, but new resources should lead with conditions.
  2. implementation_strategy lives in FabricDomainSpec but is described as 'derived from NetworkClass at creation time' — this is system-derived data that the user does not control. Per OSAC API conventions, Spec contains desired state (user-controlled) and Status contains observed state (system-controlled). Move implementation_strategy to FabricDomainStatus.
  3. Graduation criteria are just stage names ('Dev Preview → Tech Preview → GA') with no measurable conditions. The testability rubric requires concrete conditions (e.g., 'All CRUD operations pass e2e, error paths tested, no regressions in existing networking tests').
  4. Installation dimension not addressed. A new CRD (FabricDomain) requires osac-installer Helm chart changes — templates for CRD deployment, RBAC rules, and potentially new Helm values for east_west_config. The design should enumerate these installer changes.
  5. No osac.openshift.io/owner-reference annotation discussion. Even if FabricDomain is standalone (no parent resource), the design should explicitly state that owner-reference is N/A and explain why, given the workspace rule 'Never skip tenant isolation metadata' which includes owner-reference.

Suggestions (4)

  1. Add a Terminology section defining 'Server Cluster' (Netris concept), 'VPC' (as used in this design vs cloud VPC), and 'east-west' (L2/L3 lateral traffic between servers). Past networking EPs set a precedent for upfront terminology.
  2. Specify gRPC error codes for validation failures (e.g., FD-VAL-01 returns INVALID_ARGUMENT, FD-VAL-03 returns NOT_FOUND). This helps implementers and is a gap vs the F=2 calibration.
  3. Integration test section could be strengthened with test infrastructure detail — does it use a kind cluster with mock fabric manager, or does it need the real Netris lab? What fixtures are reused from existing networking tests?
  4. Documentation dimension not addressed — consider explicitly deferring it (e.g., 'API reference auto-generated from proto; user guide deferred to GA') rather than leaving it silent.

Review cost

Model: claude-opus-4-6
Cost: $0.7206
Tokens: 7 in / 6.4k out
Cache: 226.6k read
Active time: 2m 22s
API calls: 0

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

♻️ Duplicate comments (3)
enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md (3)

167-190: 🗄️ Data Integrity & Integration | 🟠 Major

Define capability derivation from fabric-manager metadata.

The design declares supports_east_west_ethernet but does not define how the value is derived from assigned manager metadata. Validation can therefore consume a manually set or stale capability. Define the derivation path and disableCapabilities behavior. Test capability changes and validation decisions.

Based on the supplied upstream unified-networking contract, NetworkClass capabilities are inferred from assigned manager metadata and published through status.

Also applies to: 217-225

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 167 - 190, Define the derivation of
NetworkClassCapabilities.supports_east_west_ethernet from assigned
fabric-manager metadata, rather than allowing it to be manually or stale-set.
Specify how disableCapabilities affects the derived and published capability,
ensure status exposes the resulting value, and add tests covering
metadata-driven capability changes and the corresponding validation decisions.

104-110: 🗄️ Data Integrity & Integration | 🟠 Major

Persist a stable provisioning identity and generation.

Resize relies on desiredConfigVersion, but the proto, CRD, and database sections do not define its source or persistence. The AAP role finds clusters by name, but the design does not define a stable name or idempotency key. Concurrent updates and retry-after-success can target the wrong cluster or accept a stale callback.

Persist an immutable FabricDomain-derived key, backend_id, and desired generation. Reject stale callbacks. Cover retries, renames, and overlapping updates.

Also applies to: 232-236, 254-262, 316-325

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 104 - 110, Define in the design a stable immutable FabricDomain-derived
provisioning identity (`backend_id` or equivalent), its source, and persistence
across the proto, CRD, and database; use it as the Netris/AAP idempotency and
lookup key rather than a mutable name. Specify how desired generations are
persisted, incremented, associated with jobs, and validated so stale or
duplicate callbacks are rejected, including retry-after-success, renames, and
overlapping updates.

112-114: 🗄️ Data Integrity & Integration | 🟠 Major

Define tenant-scoped expansion for default FabricDomains.

NetworkDefaults.default_fabric_domains is referenced without a schema or expansion rule. The design does not define how required servers, network_class, and virtual_networks values are resolved per tenant. Concrete server lists could be reused across tenants.

Define a tenant-scoped profile with per-tenant server resolution, or disable automatic defaults until allocation exists. Add an explicit opt-out path.

Also applies to: 177-180, 381-397

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 112 - 114, Define the schema and tenant-scoped expansion rules for
NetworkDefaults.default_fabric_domains, including how servers, network_class,
and virtual_networks are resolved for each tenant without reusing concrete
server lists. Specify the required allocation/profile mechanism, or disable
automatic defaults until that mechanism exists, and document an explicit tenant
opt-out path in the related sections.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md`:
- Line 33: Update the “FabricDomain ↔ VirtualNetwork Relationship” heading in
the design document to use the consecutive ### level after the preceding ##
heading, unless an intermediate section is intentionally added.
- Around line 193-202: Update FabricDomainSpec and its
fulfillment-service/operator mapping to explicitly handle the resolved
template_id and implementation_strategy values end to end. Ensure these fields
are derived from the proto or resolved only by the operator, and reject or
ignore user-provided overrides rather than exposing writable derived
configuration in the CRD.
- Around line 281-295: Update the Phase 1 authorization design and RBAC sections
to require explicit Cloud Infrastructure Admin authorization for physical server
assignments and NetworkClass/template selection on both API and CRD paths. Add
authoritative inventory validation for server ownership or assignment before
dispatch, and replace the statement that any admin may assign any server;
preserve tenant scoping for virtual network resources.
- Around line 213-225: Expand NC-VAL-09 and the associated admission/dispatch
validation to require a valid ethernet_ew template_id before dispatch, including
missing, malformed, and nonexistent template references. Define whether
template_id is immutable after creation or requires explicit versioning, then
document and test missing, invalid, and changed values so invalid configurations
cannot reach AAP.
- Around line 63-67: Update the capability rename described in the design so
version-skew compatibility is explicit: retain a deprecated supports_east_west
alias or define a migration to supports_east_west_ethernet, covering AAP
metadata and older consumers in addition to fulfillment-service and
osac-operator. Add mixed-version tests and document the required AAP,
fulfillment-service, and operator upgrade order, while preserving the
additive-change claim only if the compatibility path supports it.
- Around line 35-42: Define deterministic VPC mapping for
FabricDomain–VirtualNetwork associations across the design’s API, provisioning,
and status sections: specify behavior for zero, one, multiple, added, and
removed VNs, including ownership and cleanup of VPCs created without a VN and
migration semantics when associations change. Prefer enforcing a single-VN rule
unless shared-VPC ownership and destructive migration are explicitly defined,
and add tests covering every association mode.
- Around line 149-162: Define a single canonical lifecycle-status contract
across the FabricDomain proto, CRD status, feedback synchronization, and
workflow states. Extend FabricDomainState to cover progressing and deleting,
then document explicit proto-to-CRD mappings for state/phase, messages,
provisioningJobs, conditions, and backend identifiers across the referenced
status sections.
- Around line 263-295: Define FabricDomain server-assignment semantics for
active ethernet_ew domains by rejecting any server already assigned to another
active domain unless authoritative fabric-manager inventory explicitly supports
multi-attachment. Update validation for both create and update paths, and add
conflict tests covering overlapping servers across active FabricDomains.

---

Duplicate comments:
In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md`:
- Around line 167-190: Define the derivation of
NetworkClassCapabilities.supports_east_west_ethernet from assigned
fabric-manager metadata, rather than allowing it to be manually or stale-set.
Specify how disableCapabilities affects the derived and published capability,
ensure status exposes the resulting value, and add tests covering
metadata-driven capability changes and the corresponding validation decisions.
- Around line 104-110: Define in the design a stable immutable
FabricDomain-derived provisioning identity (`backend_id` or equivalent), its
source, and persistence across the proto, CRD, and database; use it as the
Netris/AAP idempotency and lookup key rather than a mutable name. Specify how
desired generations are persisted, incremented, associated with jobs, and
validated so stale or duplicate callbacks are rejected, including
retry-after-success, renames, and overlapping updates.
- Around line 112-114: Define the schema and tenant-scoped expansion rules for
NetworkDefaults.default_fabric_domains, including how servers, network_class,
and virtual_networks are resolved for each tenant without reusing concrete
server lists. Specify the required allocation/profile mechanism, or disable
automatic defaults until that mechanism exists, and document an explicit tenant
opt-out path in the related sections.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f11a1570-921a-4b49-9880-4808d52adb76

📥 Commits

Reviewing files that changed from the base of the PR and between d6d3a03 and 53aec02.

📒 Files selected for processing (1)
  • enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md

Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment on lines +263 to +295
#### Multiple FabricDomains

A tenant can have multiple FabricDomains with independent lifecycles:

```yaml
# GPU east-west
- name: tenant-a-gpu-ew
type: ethernet_ew
servers: ["hgx-00", "hgx-01", "hgx-02", "hgx-03"]

# Storage east-west (different servers, same tenant)
- name: tenant-a-storage-ew
type: ethernet_ew
servers: ["storage-00", "storage-01"]
```

Each has independent create/resize/delete lifecycle. In Phase 2, a tenant might have `ethernet_ew` + `infiniband_ew` FabricDomains — separate resources with separate controllers.

#### Phase 1 Limitations

- **No server eligibility validation.** Admin is trusted to supply correct hostnames. Server list membership is not restricted beyond existing tenant scoping — any Cloud Infrastructure Admin can assign any server to a FabricDomain. Phase 2+ will add HostType-based validation.
- **No automatic server pool assignment.** Explicit server lists only.
- **Depends on pre-existing Server Cluster Templates** on the Netris Controller.
- **`template_id` resolved from NetworkClass** — still Netris-specific in Phase 1, but scoped to NC config rather than appearing on every FabricDomain.
- **VPC-Server Cluster VNet coexistence validated** on zeus12 — no conflicts.

#### Virtual Clusters and VMaaS

Phase 1 targets bare-metal servers whose NICs are directly attached to the fabric. VMs need SR-IOV for high-performance EW. The FabricDomain model extends naturally via new `type` values (e.g., `ethernet_ew_sriov`). Basic VM EW isolation (without RDMA) works today via CUDN (OSAC-1589).

#### Hardware Eligibility Validation (Phase 2+)

Phase 1 relies on admin knowledge + Netris discovery. Phase 2+ adds HostType-based validation and fabric manager authoritative checks. The FabricDomain API shape does not change — only admission validation becomes stricter.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files matching design/security/fabric =="
git ls-files | rg -i '(^|/)design\.md$|fabric|fabricdomain|multifabric|netris|OSAC-1382|enhancements' | head -200

echo
echo "== target file excerpt =="
file="enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md"
if [ -f "$file" ]; then
  nl -ba "$file" | sed -n '1,380p'
else
  fd -a 'design.md' . | sed -n '1,50p'
fi

echo
echo "== search server eligibility/overlap validation terms =="
rg -n -i "multiple fabricdomains|FabricDomains|fabricdomain|fabric manager|multi-domain|overlapping|share|server list|servers|eligibility|multi-attachment|SR-IOV|infiniband|ethernet_ew|validation" enhancements . --glob '!vendor' --glob '!node_modules' --glob '!dist' --glob '!build' | head -300

Repository: osac-project/enhancement-proposals

Length of output: 3996


🏁 Script executed:

#!/bin/sh
set -euo pipefail

file="enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md"

echo "== target file excerpt (1-420) =="
awk '{ printf "%6d\t%s\n", NR, $0 }' "$file" | sed -n '1,420p'

echo
echo "== target file excerpt (420-800) =="
awk '{ printf "%6d\t%s\n", NR, $0 }' "$file" | sed -n '420,800p'

echo
echo "== search FabricDomain/multi-domain/overlap terms in enhancements =="
rg -n -i "Multiple FabricDomains|FabricDomains|fabricdomain|FabricDomain|fabric-manager|fabric manager|multi-domain|multi-attachment|overlap|server eligibility|Server Cluster Templates|HostType|Server Cluster|ethernet_ew|infiniband_ew|SR-IOV|VPC-Server Cluster" enhancements/OSAC-1382-multi-fabric-east-west-networking enhancements --glob '*.md' | head -400

Repository: osac-project/enhancement-proposals

Length of output: 50393


Define exclusive server assignment semantics.

FabricDomain validation currently requires only a non-empty servers list, and multiple FabricDomains are independent. A server can therefore be advertised in multiple active ethernet_ew Server Clusters unless the spec defines supported multi-attachment. Reject overlapping servers by default, or explicitly support cross-cluster multi-attachment and enforce it against authoritative fabric-manager inventory. Add create and update conflict tests for overlaps across active domains.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 263 - 295, Define FabricDomain server-assignment semantics for active
ethernet_ew domains by rejecting any server already assigned to another active
domain unless authoritative fabric-manager inventory explicitly supports
multi-attachment. Update validation for both create and update paths, and add
conflict tests covering overlapping servers across active FabricDomains.

Comment on lines +281 to +295
#### Phase 1 Limitations

- **No server eligibility validation.** Admin is trusted to supply correct hostnames. Server list membership is not restricted beyond existing tenant scoping — any Cloud Infrastructure Admin can assign any server to a FabricDomain. Phase 2+ will add HostType-based validation.
- **No automatic server pool assignment.** Explicit server lists only.
- **Depends on pre-existing Server Cluster Templates** on the Netris Controller.
- **`template_id` resolved from NetworkClass** — still Netris-specific in Phase 1, but scoped to NC config rather than appearing on every FabricDomain.
- **VPC-Server Cluster VNet coexistence validated** on zeus12 — no conflicts.

#### Virtual Clusters and VMaaS

Phase 1 targets bare-metal servers whose NICs are directly attached to the fabric. VMs need SR-IOV for high-performance EW. The FabricDomain model extends naturally via new `type` values (e.g., `ethernet_ew_sriov`). Basic VM EW isolation (without RDMA) works today via CUDN (OSAC-1589).

#### Hardware Eligibility Validation (Phase 2+)

Phase 1 relies on admin knowledge + Netris discovery. Phase 2+ adds HostType-based validation and fabric manager authoritative checks. The FabricDomain API shape does not change — only admission validation becomes stricter.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major

Enforce authorization for physical servers and fabric configuration.

The Phase 1 limitation permits any Cloud Infrastructure Admin to assign any server. The RBAC section only repeats VirtualNetwork tenant scoping. Tenant scoping does not authorize physical inventory claims or NetworkClass template selection.

Require explicit admin authorization on API and CRD paths. Validate server ownership or assignment against authoritative inventory before dispatch.

Also applies to: 312-330

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 281 - 295, Update the Phase 1 authorization design and RBAC sections to
require explicit Cloud Infrastructure Admin authorization for physical server
assignments and NetworkClass/template selection on both API and CRD paths. Add
authoritative inventory validation for server ownership or assignment before
dispatch, and replace the statement that any admin may assign any server;
preserve tenant scoping for virtual network resources.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

AI Design Review: EP-179

Score: 5/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Strong implementation detail: proto schemas with field types, enumerated validation rules (FD-VAL-01 through FD-VAL-07, NC-VAL-09), failure handling table with recovery paths, specific risks with concrete mitigations (pin collection version, AAP fails fast, polling loop). All CRUD lifecycle operations covered. Drawbacks section steel-mans the new-resource-type cost. Validated on zeus12 hardware. Minor gaps: no gRPC error codes specified per validation failure, resize semantics for virtual_networ
Testability 1/2 Test plan covers all three levels with some specifics: unit tests enumerate validation rules and reconciler callbacks; e2e tests describe concrete scenarios on netris-lab including VNet coexistence and error paths. However, integration tests lack infrastructure detail (doesn't specify kind cluster setup, mock backends, or fixtures). Graduation criteria are the biggest gap — 'Dev Preview → Tech Preview → GA' names stages without defining concrete conditions for progression (what must be true to m
Scope 1/2 Clear boundaries with strong alternatives section (four alternatives with specific rejection rationale). PRD referenced in frontmatter. Non-goals are specific and tied to phases/tickets. However, two relevant cross-cutting dimensions from osac-dimensions.md are not addressed or explicitly deferred: Installation (new CRD + AAP playbooks likely need Helm chart changes in osac-installer, but no mention) and Documentation (no discussion of admin guides or API reference for the new resource type). Th
Architecture 1/2 Core patterns mostly followed: standard object shape (id, Metadata, Spec, Status), RunProvisioningLifecycle, NetworkClass pluggable architecture, tenant isolation via metadata.tenant + OPA. Three gaps: (1) implementation_strategy lives in FabricDomainSpec but is described as 'derived from NetworkClass at creation time' — system-derived fields belong in status, not spec; (2) new resource uses FabricDomainState phase enum as the primary lifecycle indicator, but the rubric prefers conditions for ne

Verdict: A well-structured design that follows OSAC patterns and provides strong implementation detail, but lands at the pass threshold (5/8) due to gaps in spec/status ownership, vague graduation criteria, and unaddressed cross-cutting dimensions (Installation, Documentation).

Feedback: Three targeted fixes would strengthen this significantly: (1) Move implementation_strategy from FabricDomainSpec to FabricDomainStatus (it's system-derived, not user-controlled) and clarify whether conditions or phase enum is the authoritative lifecycle indicator for this new resource — OSAC convention prefers conditions for new types. (2) Add concrete graduation criteria — define what must be true for each stage transition (e.g., 'Tech Preview: all CRUD operations pass e2e on netris-lab, resize tested, no regressions in existing networking tests'). (3) Address Installation (what Helm chart changes are needed in osac-installer for the new CRD and AAP playbooks?) and Documentation dimensions, even if just to explicitly defer them.

Critical (0)

None.

Important (5)

  1. Spec/status ownership violation: implementation_strategy in FabricDomainSpec is described as 'derived from NetworkClass at creation time' (line 153) — system-derived fields belong in status, not spec. This violates the OSAC convention that spec contains only desired state (user-controlled).
  2. Phase enum vs conditions ambiguity: The proto uses FabricDomainState enum (lines 163-168) and the CRD has both Phase and Conditions (lines 210-211). For new resources, OSAC prefers conditions as the primary lifecycle indicator. The design should clarify which is authoritative and consider dropping the phase enum in favor of conditions.
  3. Graduation criteria are vague: 'Dev Preview → Tech Preview → GA' (line 417) names stages but defines no concrete conditions for progression. Per the rubric, graduation criteria should be measurable conditions (e.g., 'all CRUD operations pass e2e, error paths tested, no regressions in existing networking tests').
  4. Installation dimension not addressed: A new CRD, new DB table, and new AAP playbooks likely require Helm chart changes in osac-installer (CRD registration, AAP template configuration), but the design doesn't mention installer changes.
  5. Documentation dimension not addressed: No discussion of admin guides, API reference, or architecture docs updates needed for the new FabricDomain resource type. Should be addressed or explicitly deferred.

Suggestions (5)

  1. Add a Terminology section defining key terms (FabricDomain, Server Cluster, east-west isolation domain, VPC context) — this is a hallmark of well-received OSAC designs (see networking EP).
  2. Specify gRPC error codes for each validation rule (e.g., FD-VAL-01 returns INVALID_ARGUMENT with message 'type does not match any NetworkClass capability').
  3. Clarify where FabricDomain sits in the resource hierarchy diagram from AGENTS.md — it's a new top-level networking concept that should be shown in relation to VirtualNetwork and NetworkClass.
  4. Integration test section could be more specific about test infrastructure: explicitly mention kind cluster, whether NetworkClass needs to be mocked or real, and what fixtures are needed.
  5. Explicitly declare which OSAC services are in scope (BMaaS is implied but not stated; VMaaS is discussed in 'Virtual Clusters and VMaaS' but only as a future consideration).

Review cost

Model: claude-opus-4-6
Cost: $0.3856
Tokens: 7 in / 4.6k out
Cache: 270.4k read
Active time: 1m 56s
API calls: 0

@github-actions

github-actions Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-179

Score: 5/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Strong technical depth: full proto schemas with field types, comprehensive validation rules (FD-VAL-01 through FD-VAL-07, NC-VAL-09), all CRUD lifecycle operations covered (create, resize/update, delete), specific failure modes with recovery, and Netris API integration validated on real hardware (zeus12). Risks are specific with concrete mitigations. The Drawbacks section argues FOR the proposal rather than steel-manning against it, but overall feasibility is solid.
Testability 1/2 Test plan covers all three levels (unit, integration, E2E) with reasonable specifics — unit tests enumerate validation rules and reconciler callbacks, E2E tests describe full lifecycle and VNet coexistence scenarios, and test infrastructure is identified (netris-lab on zeus12). However, graduation criteria are just stage names ('Dev Preview -> Tech Preview -> GA') with no measurable conditions for advancement, and integration test infrastructure is underspecified (no explicit mention of kind clu
Scope 1/2 Well-bounded scope with clear phase delineation (Phase 1 Ethernet EW, Phase 2 InfiniBand, Phase 3 NVLink). PRD referenced in frontmatter, non-goals are specific with ticket references (EP #107, OSAC-2341), and the Alternatives section presents 4 real alternatives with detailed rejection rationale. However, the installation dimension is relevant (new CRD + DB table require osac-installer Helm chart changes) but not addressed, and documentation needs for the new resource type are not mentioned. Si
Architecture 1/2 Core OSAC patterns are well-followed: standard object shape (id, Metadata, Spec, Status), dual-controller pattern (reconciler + feedback), pluggable architecture via NetworkClass, tenant isolation via metadata.tenant and OPA policies, established provisioning lifecycle reuse. However, resolved_template_id and implementation_strategy are placed in FabricDomainSpec despite being system-set ('set by fulfillment-service at creation time, Read-only') — spec should contain only user-controlled desired

Verdict: A solid design that follows core OSAC patterns and provides strong technical detail, passing at the threshold (5/8) with no zeros — held back by spec/status ownership issues, vague graduation criteria, and unaddressed installation dimension.

Feedback: Move resolved_template_id and implementation_strategy from FabricDomainSpec to FabricDomainStatus (or a separate resolved/computed section) since they are system-set at creation time, not user-controlled desired state — this aligns with the OSAC convention that spec is user-owned and status is system-owned. Add measurable graduation criteria for each stage (e.g., 'Dev Preview: all CRUD operations pass e2e on netris-lab; Tech Preview: multi-tenant isolation verified, resize tested under load; GA: no regressions in existing networking tests, support procedures validated'). Address the installation dimension — describe what osac-installer Helm chart changes are needed for the new FabricDomain CRD and any new configuration values.

Critical (0)

None.

Important (5)

  1. Spec/status ownership violation: resolved_template_id and implementation_strategy are described as 'set by fulfillment-service at creation time' and 'Read-only' but placed in FabricDomainSpec. Per OSAC conventions (and Kubernetes API conventions), spec contains user-controlled desired state only; system-resolved values belong in status or a dedicated resolved section.
  2. Proto uses FabricDomainState phase enum as primary lifecycle indicator, but the rubric recommends conditions for new resources. The CRD includes both Phase and Conditions, creating ambiguity about which is authoritative. For a new resource, conditions should be primary with phase derived.
  3. Installation dimension gap: the design introduces a new CRD and DB table but does not address osac-installer changes (Helm chart templates, values, prerequisites). This is a relevant cross-cutting dimension that is neither addressed nor explicitly deferred.
  4. Graduation criteria are just stage names ('Dev Preview -> Tech Preview -> GA') with no measurable conditions for advancement at each stage. The rubric requires concrete conditions, not vague milestones.
  5. Drawbacks section argues FOR the proposal ('This is justified because...') rather than steel-manning the case against it. A proper drawbacks section should honestly present the costs (maintenance burden of a new resource type across proto/DB/CRD/controllers/playbooks, operational complexity, learning curve) before the reader can weigh them.

Suggestions (4)

  1. Add explicit discussion of osac.openshift.io/owner-reference annotation on FabricDomain resources — clarify what the owner-reference should be (tenant? none?) since FabricDomain is not a child of VirtualNetwork.
  2. Resize semantics table references 'virtual_networks' (plural) but the spec field is singular 'virtual_network' — fix the inconsistency.
  3. Consider mentioning CLI commands needed for admin use in Phase 1 (e.g., 'osac get fabricdomains', 'osac describe fabricdomain'), since the CLI is a primary admin interface.
  4. Address documentation needs: at minimum, API reference for the new FabricDomain resource and admin guide for NetworkClass EW configuration.

Review cost

Model: claude-opus-4-6
Cost: $0.8014
Tokens: 10 in / 6.2k out
Cache: 417.4k read
Active time: 2m 16s
API calls: 0

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (7)
enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md (7)

271-292: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Authorization Bypass (CWE-863): Incorrect Authorization

Reachability: External

Reject server overlap by default.

The design permits one server in multiple ethernet_ew FabricDomains because Netris accepts it. Backend acceptance does not prove that traffic remains isolated between clusters or tenants. Reject overlap across active domains, or define supported multi-attachment with authoritative inventory checks and explicit traffic semantics. Add create and update conflict tests.

Also applies to: 315-315

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 271 - 292, Update the Multiple FabricDomains and Phase 1 limitations
design to reject server overlap by default across active FabricDomains,
including create and update operations. If multi-attachment remains supported,
define authoritative inventory validation and explicit traffic-isolation
semantics instead; add conflict tests covering both create and update paths.

289-292: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Authorization Bypass (CWE-862): Missing Authorization

Reachability: External

Authorize physical server assignment separately from tenant scoping.

Line 291 allows any Cloud Infrastructure Admin to assign any server. Line 350 provides only tenant and OPA scoping. A tenant-scoped request can therefore select a server assigned to another tenant. Validate assignment against authoritative inventory and enforce explicit server-assignment permission on API and CRD paths before AAP dispatch.

Also applies to: 333-350

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 289 - 292, Update the server-assignment flows described in the Phase 1
limitations and the tenant/OPA scoping section to validate each selected server
against authoritative inventory and its tenant ownership, rather than trusting
supplied hostnames. Enforce a distinct physical-server assignment permission on
both API and CRD paths before dispatching to AAP, while preserving existing
tenant and OPA authorization checks.

112-114: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Define default_fabric_domains before enabling onboarding.

NetworkDefaults.default_fabric_domains is referenced but not declared in the shown schema. Each FabricDomainSpec also requires network_class and concrete servers. Define the default entry, tenant-scoped expansion, server resolution, and opt-out behavior. If Phase 1 has no allocator, disable automatic defaults. Otherwise, OSAC-2341 cannot create valid tenant resources.

Also applies to: 184-187

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 112 - 114, Define NetworkDefaults.default_fabric_domains in the schema
before enabling tenant onboarding, including a valid FabricDomainSpec with
network_class and concrete servers. Specify how defaults expand per tenant, how
server references resolve, and how tenants opt out; if Phase 1 lacks an
allocator or server-resolution path, disable automatic default provisioning
until OSAC-2341 supports valid resources.

104-110: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Persist and reuse a stable backend identity.

Line 106 uses cluster-name lookup, but the design does not define a stable idempotency key or reuse of FabricDomainStatus.backend_id. Derive the key from immutable FabricDomain.id and tenant. Persist the backend ID after success and reuse it for retry, rename, resize, and delete. Otherwise, a retry can create a duplicate cluster or target the wrong cluster.

Also applies to: 337-346

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 104 - 110, Define a stable backend idempotency key from immutable
FabricDomain.id and tenant, and use it for all create, retry, rename, resize,
and delete operations instead of relying on cluster-name lookup. After
successful creation or reconciliation, persist the backend identifier in
FabricDomainStatus.backend_id and reuse that value for subsequent AAP jobs,
including deletion, while preserving it across renames and resizes.

174-182: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Define the source of supports_east_west_ethernet.

FD-VAL-01 consumes this capability, but the design only adds a boolean field. Define how fabric-manager metadata derives the value and how the value is published and refreshed. A false default can reject a supported NetworkClass. A stale true value can dispatch to an unsupported backend.

Also applies to: 221-232

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 174 - 182, Define the authoritative fabric-manager metadata source and
derivation rules for NetworkClassCapabilities.supports_east_west_ethernet,
including how the value is published, refreshed, and handled when metadata is
missing or stale. Update the related design sections and FD-VAL-01 behavior to
prevent false defaults from rejecting supported classes or stale true values
from selecting unsupported backends.

154-169: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Define one lifecycle-status contract.

The proto exposes state, message, hub, backend_id, and vpc_id. The CRD exposes phase, provisioningJobs, conditions, backendId, and vpcId. Feedback only synchronizes part of this state. Define the conversion for every field and legal phase value. Align PROVISIONING with Progressing and define deletion and status-removal behavior.

Also applies to: 212-218, 242-244, 337-345

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 154 - 169, Define a complete lifecycle-status contract across
FabricDomainStatus and the CRD status: map state/message/hub/backend_id/vpc_id
to phase/provisioningJobs/conditions/backendId/vpcId, enumerate legal phase
values, and specify conversion behavior for every field. Ensure PROVISIONING
maps to Progressing, and explicitly define deletion handling and when status is
removed, covering the related status sections as well.

221-232: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Validate template_id before dispatch.

NC-VAL-09 does not require a non-empty, valid, or existing template ID. It also does not define update behavior. A bad template can reach AAP and fail after FabricDomain creation. Validate the template before dispatch, define immutability or versioning, and test missing, invalid, and changed values.

Also applies to: 360-366

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 221 - 232, Extend the Validation Rules around NC-VAL-09 to require
template_id to be present, valid, and refer to an existing template before
dispatch to AAP, preventing FabricDomain creation with a bad template. Define
the update behavior by making template_id immutable or specifying its versioning
rules, and add coverage for missing, invalid, and changed values in the relevant
validation tests.
🧹 Nitpick comments (1)
enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md (1)

398-418: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy lift

Add tests for the cross-layer failure paths.

Add tests for VPC reassignment, retry-after-success with persisted backend_id, status conversion, default expansion, resolved-field override rejection, template validation, server ownership, and overlap conflicts. The current plan does not cover these contracts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md` around
lines 398 - 418, Add cross-layer tests to the Test Plan covering VPC
reassignment, retry-after-success using persisted backend_id, status conversion,
default expansion, rejection of resolved-field overrides, template validation,
server ownership, and overlap conflicts. Place these scenarios across the
appropriate unit, integration, or E2E sections and preserve the existing
lifecycle and error-path coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md`:
- Around line 35-42: Define explicit update semantics for the singular
FabricDomainSpec.virtual_network field and align the virtual_networks add/remove
update section accordingly. Either specify the complete mutable transition
behavior, including VPC migration, ownership and cleanup, and vpc_id updates, or
state that changes are rejected after creation and document that validation
rule.
- Line 23: Resolve the contradiction in the design between the statement on Line
23 that backend fields are not exposed and the description on Line 252 where
fulfillment-service writes `resolved_template_id` and `implementation_strategy`
as public FabricDomainSpec fields. Either move these resolved fields to status
or internal state instead of the public spec, or define an explicit validation
mechanism that rejects user-supplied values for these fields while explaining
the proto-to-CRD-to-AAP mapping. Ensure the resolution is consistently reflected
across all affected sections including Lines 146-151, 203-210, 248-256, and
333-335.
- Around line 65-67: Document explicit rollout gating for FabricDomain creation:
define the behavior when the FabricDomain CRD is absent from the API and when
the operator/controller is not installed, including whether creation is
rejected, deferred, or ignored. Update the FabricDomains/Create flow and the
skew-handling guidance so FS persistence and CR creation follow the same
supported-state rules, while preserving normal creation once the CRD and
controller are available.

---

Duplicate comments:
In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md`:
- Around line 271-292: Update the Multiple FabricDomains and Phase 1 limitations
design to reject server overlap by default across active FabricDomains,
including create and update operations. If multi-attachment remains supported,
define authoritative inventory validation and explicit traffic-isolation
semantics instead; add conflict tests covering both create and update paths.
- Around line 289-292: Update the server-assignment flows described in the Phase
1 limitations and the tenant/OPA scoping section to validate each selected
server against authoritative inventory and its tenant ownership, rather than
trusting supplied hostnames. Enforce a distinct physical-server assignment
permission on both API and CRD paths before dispatching to AAP, while preserving
existing tenant and OPA authorization checks.
- Around line 112-114: Define NetworkDefaults.default_fabric_domains in the
schema before enabling tenant onboarding, including a valid FabricDomainSpec
with network_class and concrete servers. Specify how defaults expand per tenant,
how server references resolve, and how tenants opt out; if Phase 1 lacks an
allocator or server-resolution path, disable automatic default provisioning
until OSAC-2341 supports valid resources.
- Around line 104-110: Define a stable backend idempotency key from immutable
FabricDomain.id and tenant, and use it for all create, retry, rename, resize,
and delete operations instead of relying on cluster-name lookup. After
successful creation or reconciliation, persist the backend identifier in
FabricDomainStatus.backend_id and reuse that value for subsequent AAP jobs,
including deletion, while preserving it across renames and resizes.
- Around line 174-182: Define the authoritative fabric-manager metadata source
and derivation rules for NetworkClassCapabilities.supports_east_west_ethernet,
including how the value is published, refreshed, and handled when metadata is
missing or stale. Update the related design sections and FD-VAL-01 behavior to
prevent false defaults from rejecting supported classes or stale true values
from selecting unsupported backends.
- Around line 154-169: Define a complete lifecycle-status contract across
FabricDomainStatus and the CRD status: map state/message/hub/backend_id/vpc_id
to phase/provisioningJobs/conditions/backendId/vpcId, enumerate legal phase
values, and specify conversion behavior for every field. Ensure PROVISIONING
maps to Progressing, and explicitly define deletion handling and when status is
removed, covering the related status sections as well.
- Around line 221-232: Extend the Validation Rules around NC-VAL-09 to require
template_id to be present, valid, and refer to an existing template before
dispatch to AAP, preventing FabricDomain creation with a bad template. Define
the update behavior by making template_id immutable or specifying its versioning
rules, and add coverage for missing, invalid, and changed values in the relevant
validation tests.

---

Nitpick comments:
In `@enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md`:
- Around line 398-418: Add cross-layer tests to the Test Plan covering VPC
reassignment, retry-after-success using persisted backend_id, status conversion,
default expansion, rejection of resolved-field overrides, template validation,
server ownership, and overlap conflicts. Place these scenarios across the
appropriate unit, integration, or E2E sections and preserve the existing
lifecycle and error-path coverage.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f7e04747-3029-47a8-92d9-bad706d09ae6

📥 Commits

Reviewing files that changed from the base of the PR and between 53aec02 and 113e52f.

📒 Files selected for processing (1)
  • enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md

Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
Comment thread enhancements/OSAC-1382-multi-fabric-east-west-networking/design.md Outdated
@github-actions

github-actions Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-179

Score: 6/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Proto schemas present with full message definitions. Validation rules enumerated (FD-VAL-01 through FD-VAL-07, NC-VAL-09). All lifecycle operations covered via standard CRUD + Signal. Resize semantics with immutability table. Failure modes documented with recovery paths. Four specific risks with concrete mitigations. Template ID resolution described step-by-step.
Testability 1/2 Unit tests name specific validation rules and scenarios (template resolution, reconciler callbacks, re-provisioning triggers). E2E tests describe full lifecycle on netris-lab with isolation verification. However, integration tests are vague on infrastructure (no mention of kind cluster or mocked fabric manager). Graduation criteria are just maturity stage names ('Dev Preview -> Tech Preview -> GA') without measurable conditions — this is effectively a placeholder.
Scope 2/2 Clear 4-sentence summary. Goals are user-visible outcomes. Non-goals are specific with phase assignments (InfiniBand Phase 2, NVLink Phase 3, pool-based assignment deferred). PRD referenced in frontmatter. Four alternatives with thorough rejection rationale. Cross-cutting dimensions addressed: networking (core), tenant onboarding (OSAC-2341), UI (deferred, admin-only), E2E (netris-lab). Installation dimension partially addressed (new CRD/DB noted but no Helm chart details).
Architecture 1/2 Standard object shape (id, Metadata, Spec, Status) followed. Spec/status ownership correctly separated. Controller pattern uses RunProvisioningLifecycle with dual-controller pattern (provisioning + feedback). Pluggable architecture via NetworkClass is well-designed. Dependencies across fulfillment-service, osac-operator, osac-aap clearly identified. However: (1) design uses a FabricDomainState phase enum for a new resource when OSAC convention prefers conditions as primary lifecycle state, (2) n

Verdict: Solid design with clear scope, strong alternatives analysis, and deep implementation detail, but held back from top marks by a phase enum on a new resource (conditions preferred), vague graduation criteria, and missing terminology definitions.

Feedback: Define measurable graduation criteria for each maturity stage (e.g., 'Tech Preview: all CRUD operations pass e2e, error paths tested, no regressions in existing networking tests; GA: two production tenants using FabricDomain for 30+ days with no manual intervention'). For the FabricDomainState enum, either make conditions the primary lifecycle mechanism (the OSAC convention for new resources) and demote the phase enum, or justify why this resource needs phase-based state. Add a Terminology section near the top defining 'fabric domain,' 'east-west traffic,' 'isolation domain,' and 'Server Cluster' — the networking EP (review-patterns.md reference) set the precedent.

Critical (0)

None.

Important (3)

  1. FabricDomainState phase enum used as primary lifecycle state for a brand-new resource. OSAC convention (architecture-patterns.md, design rubric) prefers conditions for new resources. The CRD includes Conditions but the proto uses a state enum and the workflow diagrams reference 'Phase: Ready' — making the enum the primary mechanism. Either switch to conditions-first or justify the deviation.
  2. Graduation criteria ('Dev Preview -> Tech Preview -> GA') are maturity stage names without measurable conditions. The rubric requires concrete, measurable criteria at each level — not just the stage labels. Specify what must be true to graduate (e.g., 'all CRUD + error paths pass E2E, two production tenants, no manual FM cleanup needed').
  3. No terminology definitions section. review-patterns.md notes the networking EP defined terms upfront and expects the same for networking-adjacent designs. 'Fabric domain,' 'east-west traffic,' 'isolation domain,' 'Server Cluster,' and 'VPC context' are used throughout without formal definitions, which could cause confusion with different fabric manager backends.

Suggestions (5)

  1. Specify gRPC error codes for each validation rule failure (e.g., FD-VAL-01 returns INVALID_ARGUMENT, FD-VAL-03 returns NOT_FOUND). This helps implementers and test authors.
  2. Address the installation dimension explicitly — what Helm chart changes (osac-installer) are needed for the new CRD, new AAP playbook templates, and any new ConfigMap or values entries?
  3. Integration tests should specify infrastructure setup: kind cluster with mocked fabric manager or Netris stub, how AAP dispatch is simulated, and whether the NC + FD creation flow runs end-to-end or with mocked backends.
  4. Add risks for concurrent operations: what happens if two FabricDomain updates race (both changing servers list)? What if a NetworkClass is deleted while FabricDomains reference it? The immutability rules handle some cases but not all.
  5. Clarify owner-reference annotation usage for the optional FabricDomain-to-VirtualNetwork relationship. Since the relationship is 'non-owning,' explicitly state that no owner-reference annotation is set and explain the lifecycle implications (e.g., VN deletion does not cascade).

Review cost

Model: claude-opus-4-6
Cost: $0.9245
Tokens: 16 in / 7.9k out
Cache: 464.5k read
Active time: 3m 15s
API calls: 0

@vladikr
vladikr force-pushed the design/OSAC-1382 branch 3 times, most recently from 4e34f98 to b4c6cf7 Compare August 6, 2026 19:15
@jingczhang

jingczhang commented Aug 7, 2026 •

Copy link
Copy Markdown

Below is a point-by-point response to the arguments for FabricDomain over ServerCluster.

# Vladik's Concern Response
1 VirtualNetwork is an IP construct (L3 routing domain). IB PKeys and NVLink partitions are non-IP fabric constructs with no relationship to IP routing. Making ServerCluster a child of VirtualNetwork implies these non-IP things are "owned by" an IP boundary, which is a conceptual mismatch. ServerCluster groups servers. It is the same group of servers that need isolated IP communication and also need isolated IB communication. They naturally align because tenant isolation applies to all fabrics simultaneously. Indeed, VPC (AWS, CoreWeave, Netris) should be the tenant isolation boundary not VirtualNetwork. The conceptual mismatch only exists if you believe a tenant would want different server groupings per fabric (e.g., servers 1-8 share Ethernet but only servers 1-4 share IB). In practice, tenant isolation applies uniformly — same servers, all fabrics, one boundary.
2 Independent lifecycle — create/teardown NVLink partition without touching the VirtualNetwork. Incorrect. ServerCluster can be created/deleted independently — the parent VPC persists. Same as Subnet: deleting a Subnet doesn't delete its VPC.
3 With FabricDomain (orthogonal to VPC), you could create one isolation domain and associate it with multiple VPCs. With ServerCluster-as-child-of-VPC, each ServerCluster belongs to exactly one VPC — no sharing. Incorrect. ServerCluster belongs to one VPC, but storage nodes can be shared by VPCs. One deployment use case I provided is two VPCs sharing the same storage nodes while having a dedicated GPU server cluster.
4 With FabricDomain, the admin always creates the same resource type regardless of backend — FabricDomain type=ethernet_ew, FabricDomain type=infiniband, FabricDomain type=nvlink. It's one uniform resource for everything. NetworkClass resolves the backend. Incorrect. "ServerCluster" in OSAC is OSAC's resource name for "group these servers, apply this template." The NetworkClass determines which backend gets called — Netris, UFM, NMX-C, whatever. Netris just enjoys a direct pairing.
5 If you pick ServerCluster-under-VN now (because it's simpler for Phase 1 Ethernet), and later discover you need VN-independent isolation domains (for IB/NVLink that aren't VPC-scoped), you'll be in trouble. I don't see any limitation in ServerCluster compared with FabricDomain so far. But indeed, we need VPC as the tenant isolation boundary — not the current VirtualNetwork, although VirtualNetwork is mapped to Netris's VPC in the implementation.

@ori-amizur

Copy link
Copy Markdown

Phase 1: does a separate FabricDomain resource earn its keep?

Following the discussion on this PR, a few observations lead to a simpler conclusion for Phase 1:

  1. Phase 1 is entirely Ethernet-based — the only supported type is ethernet_ew, the only backend is Netris.
  2. FabricDomain depends on VirtualNetwork anyway — it requires exactly one VN, the Server Cluster is created inside the VN's Netris VPC, and there's a finalizer on the VN.
  3. The independence argument applies to Phase 2/3, not Phase 1. InfiniBand (UFM) and NVLink (NMX-C/NICo) are what motivate a separate isolation plane, but those aren't part of Phase 1.

Given this, introducing a full new resource (CRD, DB table, gRPC service, controller, AAP playbooks) for something that's tightly coupled to VirtualNetwork in Phase 1 may not be justified.

The pragmatic alternative: extend VirtualNetwork with east-west properties for Phase 1. Learn from real usage. Then design the independent resource for Phase 2 when non-Ethernet fabrics bring concrete requirements.

@jingczhang

jingczhang commented Aug 13, 2026 •

Copy link
Copy Markdown

Hi @vladikr I am happy we are converging and you plan to include uniform isolation in your FabricDomain solution. Comments from @ori-amizur is also interesting, I for sure agree with creating OSAC networking resources (VPC, VirtualNetwork) does not trigger fabric manager actions — there's nothing for the backend to actually do. NetworkAttachment triggers backend actions.

Details matter, so I figure concrete example will speak for itself.

OSAC CLI:
osac create servercluster --vpc tenant-a
--node-selector osac.openshift.io/gpu-type=h100,osac.openshift.io/rack=rack-a
--network-attachment virtualNetwork=gpu-ew,subnet=gpu-ew-subnet,interfaces=eth1+eth2+eth3+eth4+eth5+eth6+eth7+eth8
--network-attachment virtualNetwork=north-south,subnet=ns-subnet,interfaces=eth9+eth10
--nvlink
--name gpu-a

OSAC CLuster CR:
apiVersion: osac.openshift.io/v1alpha1
kind: ServerCluster
metadata:
name: gpu-a
namespace: osac
spec:
vpc: tenant-a
nodeSelector:
osac.openshift.io/gpu-type: h100
osac.openshift.io/rack: rack-a
networkAttachments:
- virtualNetwork: gpu-ew
subnet: gpu-ew-subnet
interfaces: [eth1, eth2, eth3, eth4, eth5, eth6, eth7, eth8]
- virtualNetwork: north-south
subnet: ns-subnet
interfaces: [eth9, eth10]
nvlink: true

Expected Status (after reconciliation)
apiVersion: osac.openshift.io/v1alpha1
kind: ServerCluster
metadata:
name: gpu-a
namespace: osac
spec:
vpc: tenant-a
nodeSelector:
osac.openshift.io/gpu-type: h100
osac.openshift.io/rack: rack-a
networkAttachments:
- virtualNetwork: gpu-ew
subnet: gpu-ew-subnet
interfaces: [eth1, eth2, eth3, eth4, eth5, eth6, eth7, eth8]
- virtualNetwork: north-south
subnet: ns-subnet
interfaces: [eth9, eth10]
nvlink: true
status:
observedGeneration: 1
state: Ready
backendID: "netris-sc-4a7b2c"
servers:
- gpu-01
- gpu-02
- gpu-03
- gpu-04
- gpu-05
- gpu-06
- gpu-07
- gpu-08
- gpu-09
- gpu-10
...
- gpu-32
nvlinkPartition: nvl-gpu-a
networkAttachmentStatuses:
- virtualNetwork: gpu-ew
subnet: gpu-ew-subnet
state: Ready
backendVNetID: "netris-vnet-ew-9f3d"
- virtualNetwork: north-south
subnet: ns-subnet
state: Ready
backendVNetID: "netris-vnet-ns-1e8a"
conditions:
- type: ServersResolved
status: "True"
reason: SelectorMatched
message: "32 servers matched nodeSelector"
- type: NetworkAttachmentsReady
status: "True"
reason: AllAttached
message: "All network attachments configured for 32 servers"
- type: NVLinkReady
status: "True"
reason: PartitionCreated
message: "NVLink partition nvl-gpu-a created for 32 servers"

Complete details including osac-operator reconciliation flows are added in my writing: https://github.com/jingczhang/osac-enhancements/tree/networking/enhancements/OSAC-1382-multi-fabric-east-west-networking#implementation-details

- Remove network_class from FabricDomainSpec — inherited from VN's
  NetworkClass (one NC per deployment)
- Use protobuf enum FabricDomainType instead of free-form string
- Add per-member status (FabricDomainMemberStatus) for server-level
  visibility on provisioning failures
- Lock resource name to FabricDomain (resolved from open questions)
- Clarify template V-Net vs OSAC Subnet coexistence with zeus12
  validation details
- Add CLI commands section (create, get, describe, edit, delete)
- Reserve fabric_domain field on BareMetalInstance/ClusterOrder as
  Phase 2 open question
- Update DB schema, validation rules, and test plan accordingly

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Vladik Romanovsky <vromanso@redhat.com>
@github-actions

Copy link
Copy Markdown

AI Design Review: EP-179

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 The design is validated on real infrastructure (zeus12 netris-lab) with the core AAP roles already implemented (PR #447). The phased approach (Ethernet Phase 1, IB Phase 2, NVLink Phase 3) de-risks delivery. The fulfillment-service → operator → AAP → Netris flow reuses proven OSAC patterns. The 1:1 VirtualNetwork constraint in Phase 1 simplifies the implementation while the schema (join table, repeated field) is forward-compatible for multi-VN in Phase 2+.
Testability 2/2 Concrete test scenarios at all three levels: unit tests map 1:1 to the six validation rules (FD-VAL-01 through FD-VAL-06), integration tests cover lifecycle and failure recovery with real kind cluster dependencies, and E2E tests leverage existing zeus12 netris-lab infrastructure for isolation verification. Condition transitions, per-member status, resize behavior, and error paths (invalid template, missing VN, AAP timeout) are all enumerated. Minor gap: no OPA policy test scenarios for tenant is
Scope 2/2 Well-defined Phase 1 boundaries with explicit non-goals (IB/NVLink implementation, VPC resource, pool-based assignment, SR-IOV, server inventory validation). The Phase 1 limitations section is honest about constraints (admin-trusted hostnames, template-only NIC mapping, bare-metal only). The 1:1 VN requirement is clearly justified as a product constraint, not a technical limitation, with the extension path documented.
Architecture 2/2 Sound two-plane model (N-S VirtualNetwork + E-W FabricDomain) with strong motivation from NVIDIA NICo/SuperPOD architectures. Follows OSAC patterns: NetworkClass pluggable config (consistent with networking-decisions.md decision #11), tenant annotation isolation, condition-based lifecycle, standard gRPC service shape. The owner-reference decision (association not ownership) is well-reasoned. Five alternatives are analyzed with clear rejection rationale. Minor gaps: no explicit finalizer design f

Verdict: A thorough and well-validated design that introduces a clean architectural separation between N-S (VirtualNetwork) and E-W (FabricDomain) isolation planes, with strong real-infrastructure validation, concrete test plans, and well-constrained Phase 1 scope — minor gaps in operator reconciliation detail and protobuf naming consistency are addressable without structural changes.

Feedback: Three items to address before merge: (1) Add an explicit finalizer section for the FabricDomain reconciler — the design references the standard OSAC operator pattern ('finalizer → status update → provisioning/deprovisioning lifecycle') everywhere else but never names the FabricDomain finalizer or describes the deprovisioning sequence that ensures the Netris Server Cluster is deleted before the CR is removed; without this, implementers may miss the cleanup guarantee. (2) Fix the protobuf enum naming: ETHERNET_EW, INFINIBAND_EW, and NVLINK should be FABRIC_DOMAIN_TYPE_ETHERNET_EW, FABRIC_DOMAIN_TYPE_INFINIBAND_EW, and FABRIC_DOMAIN_TYPE_NVLINK per protobuf and OSAC conventions (the UNSPECIFIED value is already correctly prefixed) — this will fail buf lint as written. (3) Describe how the operator propagates backend_id and vpc_id back to the fulfillment-service database after provisioning — the request path (FS → operator → AAP → Netris) is clear, but the return path for status fields sto

Critical (0)

None.

Important (3)

  1. FabricDomain reconciler finalizer design is missing — the design describes cleanup behavior ('Delete FabricDomain → delete Server Cluster') and idempotency via backend_id, but never specifies the finalizer that enforces backend cleanup before CR removal. This is a standard OSAC operator pattern (architecture-patterns.md: 'All controllers follow the same reconciliation pattern: finalizer → status update → provisioning/deprovisioning lifecycle') that should be explicit in the design.
  2. Protobuf enum values are inconsistently prefixed — FABRIC_DOMAIN_TYPE_UNSPECIFIED = 0 follows convention but ETHERNET_EW = 1, INFINIBAND_EW = 2, NVLINK = 3 do not. Per protobuf conventions and buf lint rules, these should be FABRIC_DOMAIN_TYPE_ETHERNET_EW, FABRIC_DOMAIN_TYPE_INFINIBAND_EW, FABRIC_DOMAIN_TYPE_NVLINK.
  3. Status propagation path from operator to fulfillment-service DB is unspecified — backend_id and vpc_id appear in both FabricDomainStatus (CR) and the fabric_domains table (DB), but the mechanism for syncing these after the operator provisions the Server Cluster is not described.

Suggestions (4)

  1. Add OPA policy test scenarios to the test plan — tenant isolation is enforced via OPA policies and osac.openshift.io/tenant annotation, but no test verifies that a tenant cannot read/modify another tenant's FabricDomain.
  2. Consider adding an idempotency integration test — 'operator restart mid-reconciliation: kill operator during provisioning, restart, verify it resumes correctly using backend_id match' — this is listed in the failure handling table but not in the test plan.
  3. The FabricDomainMemberState enum (PENDING, ACTIVE, FAILED) shown in FabricDomainMemberStatus is not formally defined as a protobuf enum in the API Extensions section — add it for completeness.
  4. Clarify whether FabricDomain creation is tenant-self-service or admin-only in Phase 1 — the RBAC table shows only Cloud Infrastructure Admin can create, but the workflow section says 'Cloud Infrastructure Admin creates FabricDomain' in parenthetical alongside 'Tenant Admin'. If admin-only is intentional for Phase 1, state it explicitly as a Phase 1 limitation with the extension plan.

Review cost

Model: claude-opus-4-6
Cost: $0.8952
Tokens: 12 in / 5.8k out
Cache: 554.9k read
Active time: 2m 26s
API calls: 0

@vladikr

vladikr commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Phase 1: does a separate FabricDomain resource earn its keep?

Following the discussion on this PR, a few observations lead to a simpler conclusion for Phase 1:

  1. Phase 1 is entirely Ethernet-based — the only supported type is ethernet_ew, the only backend is Netris.
  2. FabricDomain depends on VirtualNetwork anyway — it requires exactly one VN, the Server Cluster is created inside the VN's Netris VPC, and there's a finalizer on the VN.
  3. The independence argument applies to Phase 2/3, not Phase 1. InfiniBand (UFM) and NVLink (NMX-C/NICo) are what motivate a separate isolation plane, but those aren't part of Phase 1.

Given this, introducing a full new resource (CRD, DB table, gRPC service, controller, AAP playbooks) for something that's tightly coupled to VirtualNetwork in Phase 1 may not be justified.

The pragmatic alternative: extend VirtualNetwork with east-west properties for Phase 1. Learn from real usage. Then design the independent resource for Phase 2 when non-Ethernet fabrics bring concrete requirements.

Thanks Ori. I think we already discussed it and the agreement was not to extend the VirtualNetowrk
Besides, if we will extend the virtualNetwork now it will just create a breaking change later.
I also don't see a high cost for introducing the FabricDomain now. It also shows the future direction, and will have one backend. I think VirtualNetwork also started with just one backend.

@vladikr

vladikr commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Alternative: NetworkAttachment as the universal server-to-domain binding

The current design introduces a servers list on FabricDomain and a required virtual_networks link, which couples E-W to N-S despite them being conceptually independent planes.

What if NetworkAttachment could reference either a Subnet (N-S) or a FabricDomain (E-W)?

Instead of FabricDomain owning a server list and a VN reference:

  • A NetworkAttachment references a Subnet for IP/N-S connectivity (existing)
  • A NetworkAttachment references a FabricDomain for fabric/E-W isolation (new)
  • FabricDomain membership is derived from its attachments, not from a flat hostname list
  • FabricDomain has no virtual_networks field — it's truly independent

Why this might be better:

  1. Real independence. N-S and E-W are actually decoupled, not "conceptually independent but linked by a required field."
  2. Reuses an existing mechanism instead of inventing a new way to express server membership (a flat hostname list on FabricDomain).
  3. Consistent model. An admin attaches a server to a Subnet for IP, attaches the same server to a FabricDomain for fabric — same verb, same pattern.
  4. No server-list drift. The concern about keeping server lists in sync across multiple FabricDomains goes away — each server's memberships are declared on the server side via its attachments.

The Phase 1 Netris constraint (Server Cluster needs a VPC) becomes an operator implementation detail: the operator looks up which VPC the server's Subnet attachment belongs to, rather than requiring FabricDomain to declare it.

The main tradeoff is more objects (one NetworkAttachment per server per FabricDomain), but that's consistent with how Subnet attachments already work.

Thank you!
I like the idea in principle.
But I'm not entirely sure how could this work at this point.

On one hand, scale is an issue, since if you have many nodes each would need to have a CR * nics * by number of FabricDomains...
But Also, the issue is that for fabric managers (Netris, UFM, nico) we'll need to create a template with single payload with a flat server list.
So if we'll have multiple NetworkAttachment CRs, the operator has to watch, aggregate, and merge all of these objects into a flat list before making one API call.
I think it's a pretty large overhead.

For Phase 2+ BMI/VM integration, FabricDomain can evolve to reference BareMetalInstance CRs directly (via bmi_refs or label selectors) without needing per-interface attachment CRs.
VMs are a different layer kubeVirt attaches to the isolated fabric via SR-IOV VFs via multus NetworkAttachmentDefinitions, not through the FabricDomain API

Let's revisit this in Phase 2.

@vladikr

vladikr commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Hi @vladikr I am happy we are converging and you plan to include uniform isolation in your FabricDomain solution. Comments from @ori-amizur is also interesting, I for sure agree with creating OSAC networking resources (VPC, VirtualNetwork) does not trigger fabric manager actions — there's nothing for the backend to actually do. NetworkAttachment triggers backend actions.

Details matter, so I figure concrete example will speak for itself.

OSAC CLI: osac create servercluster --vpc tenant-a --node-selector osac.openshift.io/gpu-type=h100,osac.openshift.io/rack=rack-a --network-attachment virtualNetwork=gpu-ew,subnet=gpu-ew-subnet,interfaces=eth1+eth2+eth3+eth4+eth5+eth6+eth7+eth8 --network-attachment virtualNetwork=north-south,subnet=ns-subnet,interfaces=eth9+eth10 --nvlink --name gpu-a

OSAC CLuster CR: apiVersion: osac.openshift.io/v1alpha1 kind: ServerCluster metadata: name: gpu-a namespace: osac spec: vpc: tenant-a nodeSelector: osac.openshift.io/gpu-type: h100 osac.openshift.io/rack: rack-a networkAttachments: - virtualNetwork: gpu-ew subnet: gpu-ew-subnet interfaces: [eth1, eth2, eth3, eth4, eth5, eth6, eth7, eth8] - virtualNetwork: north-south subnet: ns-subnet interfaces: [eth9, eth10] nvlink: true

Expected Status (after reconciliation) apiVersion: osac.openshift.io/v1alpha1 kind: ServerCluster metadata: name: gpu-a namespace: osac spec: vpc: tenant-a nodeSelector: osac.openshift.io/gpu-type: h100 osac.openshift.io/rack: rack-a networkAttachments: - virtualNetwork: gpu-ew subnet: gpu-ew-subnet interfaces: [eth1, eth2, eth3, eth4, eth5, eth6, eth7, eth8] - virtualNetwork: north-south subnet: ns-subnet interfaces: [eth9, eth10] nvlink: true status: observedGeneration: 1 state: Ready backendID: "netris-sc-4a7b2c" servers: - gpu-01 - gpu-02 - gpu-03 - gpu-04 - gpu-05 - gpu-06 - gpu-07 - gpu-08 - gpu-09 - gpu-10 ... - gpu-32 nvlinkPartition: nvl-gpu-a networkAttachmentStatuses: - virtualNetwork: gpu-ew subnet: gpu-ew-subnet state: Ready backendVNetID: "netris-vnet-ew-9f3d" - virtualNetwork: north-south subnet: ns-subnet state: Ready backendVNetID: "netris-vnet-ns-1e8a" conditions: - type: ServersResolved status: "True" reason: SelectorMatched message: "32 servers matched nodeSelector" - type: NetworkAttachmentsReady status: "True" reason: AllAttached message: "All network attachments configured for 32 servers" - type: NVLinkReady status: "True" reason: PartitionCreated message: "NVLink partition nvl-gpu-a created for 32 servers"

Complete details including osac-operator reconciliation flows are added in my writing: https://github.com/jingczhang/osac-enhancements/tree/networking/enhancements/OSAC-1382-multi-fabric-east-west-networking#implementation-details

Thanks for your comment.
Well... a few observations on the CR example:
The nics mapping in your CR interfaces: [eth1, eth2, ...] on each networkAttachment puts the assignment on every ServerCluster instance.
In the FabricDomain model, NIC mapping lives on the Server Cluster Template (that's referenced by NetworkClass). that's configured once by infra and applied to all domains.
I think we agreed that this remains static.

The networkAttachments list includes both EW and NS subnets in one object.
VirtualNetwork and Subnet already handle north-south independently coupling them into the fabric resource means you can't manage north-south networking without touching the EW object.

The nvlink: true as a boolean... I mean, this is exactly the lifecycle coupling point.
You can't teardown an ephemeral NVLink partition without affecting the persistent ethernet domain.
Separate FabricDomains per fabric type allow independent lifecycles when they're different.
I showed that exactly in the previous comment yesterday.

Regarding the nodeSelector. I think it's an interesting idea for Phase 2, but it's a separate concern from the isolation model itself.
How servers are selected is orthogonal to how the isolation domain is modeled.
So Phase 1 uses explicit hostnames;
Phase 2 can add dynamic resolution to FabricDomain or to any other resource it doesn't require a different resource shape.
We will also have VMs in the next phases.

@jingczhang

Copy link
Copy Markdown

Hi @vladikr,
The OSAC ServerCluster solution stresses that a group of nodes has a single lifecycle. GPU capability (NVLink) is an attribute of the node, not a separate lifecycle to manage. Introducing independent lifecycle management per fabric type (Ethernet vs NVLink vs IB) for the same set of nodes adds operational complexity without clear benefit. In a sovereign cloud with hard tenant boundaries like OSAC, you wouldn't dynamically repartition NVLink between tenants. The partition matches the tenant allocation. Dynamic sub-partitioning within a single tenant's allocation is a workload scheduling concern (IMEX per-job isolation), not an OSAC infrastructure concern.

The OSAC ServerCluster solution applies to both BM and VM nodes. For VM ServerClusters with GPU support, enabling NVLink places them in the same NVLink partition — same semantics as BM.

I'd like to ask again to add the OSAC ServerCluster solution back as a design alternative. The description can be kept simple — the key differentiator is: single lifecycle for nodes, uniform isolation across all fabrics. The name is not important (ServerCluster, HostGroup, NodeGroup — group compute resources with uniform characteristics and manage them as a unit with a single lifecycle and a single security perimeter).

@vladikr

vladikr commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @jingczhang

I think there is some kind of confusion. I agree that per-job NVLink sub-partitioning inside a tenant is a scheduling concern (IMEX), not OSAC infrastructure.
But FabricDomain does not manage nor aims to manage that anyway.

What OSAC manages is which servers are in this tenant’s isolation domain on a given fabric.
That's the same class of decision as which servers are in the tenant’s Ethernet VRF.

Hardware capability is a node attribute, for sure. However, partition/VRF/PKey membership is a provisioning decision when nodes are allocated or returned.

For the common uniform case (same nodes, all fabrics, one lifecycle), we don’t need to force multiple domains. one FabricDomain and a multi-fabric NetworkClass template (or type: multi later) gives a single membership list and atomic resize. That gives the same operational shape as you're describing.

But the API should stay flexible to accommodate use cases where membership and/or lifetime is different (I already gave examples: storage off NVLink, or a domain that must be torn down without touching the long-lived Ethernet/N-S) or managers that have different models.
That’s not the default path, but the platform must support it.

ServerCluster-as-peer is already documented as Alternative #2 in the design doc. - Please take a look.

For VMs with GPU, NVLink membership is still a host/partition concern. VMs don’t independently join an NVLink domain the way a BM node does.
However, Phase 1 is still baremetal only and VM east-west will come later.

@ori-amizur

Copy link
Copy Markdown

Alternative: FabricDomain as a definition, server membership via fabricDomains array

FabricDomain is a standalone resource for all fabric types, but it defines the isolation domain -- not the server membership. Servers declare their own memberships via an immutable fabricDomains array alongside networkAttachments:

# FabricDomain -- defines the isolation domain
apiVersion: networking.osac.io/v1
kind: FabricDomain
metadata:
  name: tenant-a-gpu-ew
spec:
  type: ethernet_ew
  network_class: spectrum-x-ai
  virtual_networks:
    - tenant-a-vn          # required for Ethernet (backend needs VPC)
---
apiVersion: networking.osac.io/v1
kind: FabricDomain
metadata:
  name: tenant-a-nvlink
spec:
  type: nvlink
  network_class: nvlink-fabric
                            # no virtual_networks -- NVLink has no VPC concept
---
# Servers declare their memberships
apiVersion: osac.io/v1
kind: BareMetalInstance
metadata:
  name: hgx-01
spec:
  networkAttachments:
    - subnet: gpu-ew-subnet
    - subnet: ns-subnet
  fabricDomains:
    - tenant-a-gpu-ew
    - tenant-a-nvlink
---
apiVersion: osac.io/v1
kind: BareMetalInstance
metadata:
  name: storage-01
spec:
  networkAttachments:
    - subnet: storage-subnet
  fabricDomains:
    - tenant-a-gpu-ew       # Ethernet EW only, no NVLink

Why this approach:

  • One model for all fabrics. Ethernet, InfiniBand, and NVLink all use the same resource type. No split between "Ethernet on VirtualNetwork" and "non-IP on FabricDomain."
  • No server list on FabricDomain, no drift. Membership is the set of servers that reference it. Adding a server means provisioning it with the right fabricDomains reference.
  • Non-uniform membership is natural. hgx-01 is in both Ethernet EW and NVLink. storage-01 is in Ethernet EW only. No duplicated server lists to keep in sync.
  • Immutable, like networkAttachments. Set at provisioning, torn down at deallocation. The operator aggregates on creation/deletion events only.
  • VN link only where needed. Ethernet EW references a VirtualNetwork (backend needs VPC). InfiniBand and NVLink don't.
  • FabricDomain is simpler. It's a definition (type, network_class, optional VN reference) -- not a server registry.

@jingczhang

Copy link
Copy Markdown

Hi @vladikr, I think enough details are discussed on discrete isolation vs uniform isolation now, and my request has been for you to document uniform isolation as a design alternative. There is good reason that the majority of GPU-aaS providers use uniform isolation.

For the fabric domain solution, two things feel off, I wish you can improve them:
(1) You do not improve OSAC networking model to allow multiple virtual networks under a VPC while your Phase 1 implementation is to use Netris' ServerCluster which puts your N-S network and E-W RoCE network under the same VPC. Thanks to Netris' ServerCluster you can have communication path between the networks, but you create the gap between OSAC networking model and implementation.

(2) Your osac-cli to create a Fabric domain has to specify the N-S network in the command line, this feels very twisted. It will become common sense if you attach the fabric domain to a VPC. isn't it?
osac create fabricdomain --type ethernet_ew
--servers hgx-01,hgx-02,hgx-03,hgx-04
--virtual-network tenant-a-vn
--name tenant-a-gpu-ew

@github-actions

Copy link
Copy Markdown

AI Design Review: EP-179

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Full proto schemas with field types, enum values, and gRPC service definition including all CRUD operations plus Signal. Database schema provided (fabric_domains table, join table for VN association). Validation rules table specifies six rules with gRPC error codes. Failure handling table covers six specific failure modes with recovery paths and user-visible effects. Risks are concrete (fabric manager API changes, server overlap, template misconfiguration) with specific mitigations. Drawbacks se
Testability 2/2 Test plan covers all three levels with specific scenarios. Unit tests map directly to validation rules (FD-VAL-01 through FD-VAL-06) plus condition transitions, per-member status, and immutability enforcement. Integration tests describe four concrete scenarios including failure re-provisioning and VN deletion blocked by finalizer. E2E tests specify a full lifecycle on netris-lab including isolation verification (same-tenant ping succeeds, cross-tenant blocked), VNet coexistence, and error paths.
Scope 2/2 Summary clearly states what's added (FabricDomain), why (east-west fabric isolation is a separate plane from IP isolation), and key capabilities. Goals are user-visible outcomes. Non-goals are highly specific with rationale (no IB/NVLink Phase 1, no VPC resource, no pool-based assignment, no SR-IOV). Five alternatives thoroughly analyzed with pros/cons (ServerCluster as child, as peer, new VPC parent, fabric_bindings on VN, do nothing). PRD referenced in frontmatter. Cross-cutting dimensions cov
Architecture 2/2 All OSAC patterns followed: standard object shape (id, Metadata, Spec, Status), tenant isolation via osac.openshift.io/tenant annotation, conditions-based lifecycle (not phase enums), typed proto structures (not maps), pluggable backend via NetworkClass. Owner-reference non-applicability explicitly justified. Spec/status ownership correct (servers/type/virtual_networks in spec; conditions/backend_id/vpc_id/members in status). Affected components enumerated across fulfillment-service, osac-operat

Verdict: A thorough, well-structured design that follows all OSAC architectural patterns, provides deep implementation detail with proto schemas and database schemas, offers five substantive alternatives, and includes specific testable scenarios at every level — one of the stronger EPs reviewed.

Feedback: The SignalFabricDomain RPC appears in the gRPC service definition but is never explained — add a brief description of what signal types it supports and when it would be invoked. Integration tests should specify test infrastructure details (kind cluster with mocked Netris backend, or real netris-lab) to distinguish them from E2E tests. Since osac-installer Helm values for NetworkClass east_west_config are being extended, consider noting whether the Enclave Wizard pipeline applies for the new schema fields.

Critical (0)

None.

Important (3)

  1. SignalFabricDomain RPC is listed in the gRPC service definition (line ~191 of the design) but never explained anywhere in the document. Implementers need to know what signal types are supported, what state transitions they trigger, and which personas can invoke them. Add a row to the validation table or a subsection describing Signal semantics.
  2. Integration tests describe what scenarios are tested but not what test infrastructure they run on. The skill-prompt checklist requires integration tests to describe infrastructure (kind cluster, mocked backends, etc.). Specify whether integration tests use a kind cluster with a mocked Netris backend or a test double, and how they differ from the E2E tests that run against real netris-lab.
  3. osac-installer Helm values are being extended with east_west_config for NetworkClass. Per the Enclave Wizard pipeline (.design/context/enclave-wizard-pipeline.md), any Helm value addition should note whether the schema-to-control mapping applies and whether Enclave Wizard tasks are needed in the decomposition.

Suggestions (3)

  1. Consider adding a formal Terminology section (as the networking EP does) rather than defining N-S/E-W/FabricDomain terms inline. This makes it easier for reviewers to check consistent usage.
  2. The database schema stores backend_id and vpc_id in the fabric_domains table, but conditions live on the Kubernetes CR. Briefly clarifying this storage split (PostgreSQL for fulfillment-service CRUD, CRD for operator reconciliation state) would help implementers unfamiliar with the dual-storage pattern.
  3. The summary section is longer than the recommended 3-5 sentences due to the embedded table. Consider whether the N-S vs E-W comparison table could move to the Motivation section, keeping the Summary tighter.

Review cost

Model: claude-opus-4-6
Cost: $0.6315
Tokens: 785 in / 5.6k out
Cache: 233.7k read
Active time: 2m 18s
API calls: 0

@jingczhang

Copy link
Copy Markdown

I feel the need to add this comment. I have looked at a number of mainstream CaaS, BMaaS, VMaaS, and GPUaaS offerings and have not found any that models tenant networking using separate North-South and East-West tenancy memberships.
The common industry practice appears to be either:
(1) Dedicated node or cluster allocation, where Ethernet, InfiniBand, and GPU-fabric memberships align to the same node set; or
(2) Shared/serverless services, where only the North-South tenant network is exposed and the East-West fabric is kept as an implementation detail of the provider.
It is apparent that introducing separate North-South and East-West tenancy models increases operational complexity, ownership ambiguity, lifecycle management overhead, and troubleshooting burden.

@vladikr

vladikr commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks @jingczhang .
Sorry for the delay, I was focused on other tasks...

On uniform isolation:
Alternative #2 already documents ServerCluster-as-peer (single lifecycle, uniform isolation across fabrics) with pros/cons.
The default operational path for uniform GPU sets in the FabricDomain design is also one domain + multi-fabric NetworkClass template. same node set, one resize, not three domains by default.

Regarding VPC vs multiple networks:

In OSAC today VirtualNetwork is the VPC-like object.
Netris Server Cluster places EW and NS VNets under that one VPC;
OSAC Subnets add more VNets in the same VPC.
That matches Phase 1: one VN <-> one VPC, internal V-Nets are template/Subnet detail.
Exposing a first-class “VPC with many VirtualNetworks” hierarchy is Alternative #3 and a broader networking-model change;
it is not required to implement EW isolation on Netris. We will surely get back to this discussion in the future.

regarding CLI:

--virtual-network is the Phase 1 handle for that VPC (VN = VPC in the current model).
It is not “pass an arbitrary N-S subnet.”
If we later add a VPC resource, an alias like --vpc is fine; until then VN is the correct attachment point for Server Cluster placement.

On industry practice:

Yes, I agree that most GPU-aaS UX is uniform node allocation, or EW hidden as a provider detail.
I wrote about this in the design too.

OSAC still needs an API object for fabric isolation in a multi-tenant sovereign cloud.
Uniform case = one object / one node set. Separate N-S and E-W membership is optional for non-uniform topologies, not the primary tenant workflow.

Hyperscalers hiding EW does not remove the need to program VRF/PKey/partition isolation; it only hides it from the tenant API.

@jingczhang

Copy link
Copy Markdown

Hi @vladikr, thanks. To avoid any confusion, below is the alternative I advocate and I am done commenting -)

Use node-based isolation. A tenant is assigned nodes (bare metal or virtual). For mixed hardware, use separate node groups under the same VPC.

  • Same group → one E-W domain. Groups are by hardware class (GPU vs storage etc). That is the placement-group / cluster pattern: AWS EFA stays inside the cluster, SuperPOD compute fabric and CoreWeave HPC interconnect are per-cluster, and Netris Server Cluster is the same idea (VNI + PKey + NVLink partition).

  • Different groups, same tenant → one N-S supernet. AWS VPC CIDR, CoreWeave VPC host prefix, and Netris allocation + childSubnetPrefixLength work this way: unique child prefixes per group, L3 reachability for storage/ingress.

Per-job E-W does not change that. The NVLink partition is static ownership of the GPU node group. The AI job scheduler’s dynamic isolation runs inside that partition; it is not a second multi-tenancy lifecycle.

danmanor
danmanor previously approved these changes Aug 25, 2026

@danmanor danmanor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approval — Phase 1 design is sound, ship it

I've reviewed this design extensively, including deep dives into how 10 industry providers model east/west networking (AWS, GCP, Azure, OCI, Nebius, Crusoe, CoreWeave, Rafay, NICo, Netris), OSAC's existing networking architecture, and the full discussion between Vladik, Jing, and Ori.

Why I'm approving

The two-plane model (N/S via VirtualNetwork, E/W via FabricDomain) is architecturally correct. NVIDIA's own infrastructure controller (NICo), which manages the same backends OSAC will use (Netris, UFM, NMX-C), chose three independent isolation planes (VPC, InfiniBandPartition, NVLinkLogicalPartition). Nebius and Crusoe independently arrived at the same orthogonal model. The design is well-validated on real hardware (zeus12), follows established OSAC patterns, and has clear Phase 1 boundaries.

The Jing/Vladik debate has converged. Both agree on the core behavior; the disagreement is about resource naming and lifecycle granularity. Vladik's type: multi proposal for Phase 2/3 addresses Jing's atomic-resize concern for uniform deployments, while separate FabricDomains per type handle non-uniform cases (SuperPOD-style). ServerCluster-as-peer is documented as Alternative #2.

Items addressed in earlier reviews (Aug 3 + Aug 13)

All four concerns from my first review round have been resolved:

  1. Why VN instead of Subnet? → FabricDomain is now standalone, not on VN
  2. How will tenant know template_id? → Resolved from NetworkClass
  3. Generic enough without Netris? → Backend config scoped to NetworkClass, not FabricDomain
  4. Storage east/west? → Multiple FabricDomains with independent lifecycles

Items from my second review (Aug 13) — status

  1. Enum for type — still recommend. Every AI review flagged this. Proto enum prevents typos, provides compile-time safety. Addressable before or shortly after merge.
  2. Per-member status — still recommend for Phase 2 (IB partial membership visibility). Not blocking for Phase 1.
  3. Resolve naming — FabricDomain vs IsolationDomain. Recommend deciding before merge. FabricDomain is the stronger choice.
  4. Template scope clarification — the design now explains that the template programs both EW and NS V-Nets, with OSAC Subnets coexisting alongside. This is clear.
  5. CLI commands — Phase 1 is CLI-only, so documenting the CLI surface matters. Can be a follow-up.
  6. Reserved fabric_domain field on BareMetalInstance/Cluster — Phase 2 item.

On Ori's latest proposal (fabricDomains array on BareMetalInstance)

Ori's Aug 16 proposal — FabricDomain as a definition with membership declared on BareMetalInstance via fabricDomains: [] — is the most promising evolution path for Phase 2. It eliminates server-list drift, makes non-uniform membership natural (gpu-01 in both ethernet_ew and nvlink, storage-01 in ethernet_ew only), and aligns with how networkAttachments already work. Worth revisiting when BMI/VM integration is scoped.

On Jing's remaining concerns

  1. API/implementation gap (OSAC models N/S and E/W separately, but Netris Server Cluster handles both): This is intentional — the design models intent, not implementation. A multi-backend platform should not let one backend's holistic API shape the tenant-facing abstraction. When OSAC supports direct UFM or NICo (where there's no holistic "Server Cluster" concept), the FabricDomain API works unchanged.

  2. --virtual-network on FabricDomain create feels unnatural: Acknowledged. The VN reference is a Phase 1 product constraint (Netris needs VPC context + N/S reachability). Phase 2 can relax this to optional when non-VPC fabrics (IB, NVLink) are added. The current design explicitly documents this as a Phase 1 requirement, not a permanent architectural choice.

Recommendation

Merge Phase 1 as designed. Evolve in Phase 2 based on real usage:

  • type: multi for uniform deployments (Vladik's proposal, addresses Jing's atomic-resize)
  • fabricDomains: [] on BareMetalInstance for server-side membership (Ori's proposal, addresses drift)
  • Relax VN requirement to optional when IB/NVLink land
  • Consider network_class removal from FabricDomainSpec (one NC per deployment, can be resolved from VN)

@danmanor danmanor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approval — Phase 1 design is sound, ship it

I've reviewed this design extensively, including deep dives into how industry providers model east/west networking (hyperscalers, neoclouds, and infrastructure controllers), OSAC's existing networking architecture, and the full discussion thread.

Why I'm approving

The two-plane model (N/S via VirtualNetwork, E/W via FabricDomain) is architecturally correct. Industry infrastructure controllers that manage the same backends OSAC will use chose independent isolation planes for VPC, InfiniBand, and NVLink. Multiple neoclouds independently arrived at the same orthogonal model. The design is well-validated on real hardware (zeus12), follows established OSAC patterns, and has clear Phase 1 boundaries.

The design discussion has converged. The core behavior is agreed; the remaining disagreement is about resource naming and lifecycle granularity. The type: multi proposal for Phase 2/3 addresses the atomic-resize concern for uniform deployments, while separate FabricDomains per type handle non-uniform cases (e.g., storage off NVLink, ephemeral NVLink partitions). ServerCluster-as-peer is documented as Alternative #2.

Items addressed in earlier reviews (Aug 3 + Aug 13)

All four concerns from my first review round have been resolved:

  1. Why VN instead of Subnet? → FabricDomain is now standalone, not on VN
  2. How will tenant know template_id? → Resolved from NetworkClass
  3. Generic enough without a specific fabric manager? → Backend config scoped to NetworkClass, not FabricDomain
  4. Storage east/west? → Multiple FabricDomains with independent lifecycles

Items from my second review (Aug 13) — status

  1. Enum for type — still recommend. Every AI review flagged this. Proto enum prevents typos, provides compile-time safety. Addressable before or shortly after merge.
  2. Per-member status — still recommend for Phase 2 (IB partial membership visibility). Not blocking for Phase 1.
  3. Resolve naming — FabricDomain vs IsolationDomain. Recommend deciding before merge. FabricDomain is the stronger choice.
  4. Template scope clarification — the design now explains that the template programs both EW and NS V-Nets, with OSAC Subnets coexisting alongside. This is clear.
  5. CLI commands — Phase 1 is CLI-only, so documenting the CLI surface matters. Can be a follow-up.
  6. Reserved fabric_domain field on BareMetalInstance/Cluster — Phase 2 item.

On the NetworkAttachment / fabricDomains[] proposals

The Aug 16 proposal — FabricDomain as a definition with membership declared on BareMetalInstance via fabricDomains: [] — is the most promising evolution path for Phase 2. It eliminates server-list drift, makes non-uniform membership natural (gpu-01 in both ethernet_ew and nvlink, storage-01 in ethernet_ew only), and aligns with how networkAttachments already work. Worth revisiting when BMI/VM integration is scoped.

On remaining architectural concerns

  1. API/implementation gap (OSAC models N/S and E/W separately, but the fabric manager handles both holistically): This is intentional — the design models intent, not implementation. A multi-backend platform should not let one backend's holistic API shape the tenant-facing abstraction. When OSAC supports backends that don't have a holistic concept, the FabricDomain API works unchanged.

  2. --virtual-network on FabricDomain create feels unnatural: Acknowledged. The VN reference is a Phase 1 product constraint (backend needs VPC context + N/S reachability). Phase 2 can relax this to optional when non-VPC fabrics (IB, NVLink) are added. The current design explicitly documents this as a Phase 1 requirement, not a permanent architectural choice.

Recommendation

Merge Phase 1 as designed. Evolve in Phase 2 based on real usage:

  • type: multi for uniform deployments (addresses atomic-resize concern)
  • fabricDomains: [] on BareMetalInstance for server-side membership (addresses drift)
  • Relax VN requirement to optional when IB/NVLink land
  • Consider network_class removal from FabricDomainSpec (one NC per deployment, can be resolved from VN)

@openshift-ci

openshift-ci Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: danmanor, vladikr

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@danmanor
danmanor dismissed their stale review August 25, 2026 07:51

Replaced with updated review (removed vendor references)

@vladikr

vladikr commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

/retest

- Membership is static in Phase 1 (explicit hostnames); document that
  Phase 2 should support inventory-driven membership via selectors or
  BMI references
- FabricDomain membership is host/device-scoped; VMs attach to SR-IOV
  VFs or GPUs on hosts already in the domain, not as FD members

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Vladik Romanovsky <vromanso@redhat.com>
@openshift-ci openshift-ci Bot removed the lgtm label Aug 26, 2026
@openshift-ci

openshift-ci Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

New changes are detected. LGTM label has been removed.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-179

Score: 8/8 | Verdict: PASS
Feature: OSAC-1382

Criterion Score Notes
Feasibility 2/2 Deep technical detail throughout: full protobuf schemas with field types, SQL DDL for database schema, validation rules with specific gRPC error codes (6 rules), detailed failure handling matrix (6 failure modes with recovery), 5 specific risks with concrete mitigations, complete CLI commands, and a drawbacks section that steel-mans the argument. All CRUD lifecycle operations covered plus resize. One gap: SignalFabricDomain RPC is declared in the gRPC service definition but never described — no request/response types, workflow, or use case documented.
Testability 2/2 Test plan specifies concrete scenarios at all three levels. Unit tests enumerate all 6 validation rules by ID, template resolution, condition transitions, per-member status, and immutability enforcement. Integration tests describe lifecycle verification with condition checks, deletion cleanup, re-provision after failure simulation, and finalizer-blocked VN deletion. E2E tests describe a full lifecycle on netris-lab with isolation verification (same-tenant succeeds, cross-tenant blocked), VNet coexistence with VXLAN ID verification, and error paths. Graduation criteria are measurable: Dev Preview (unit+integration pass), Tech Preview (full E2E with error paths and no regressions), GA (production ≥2 tenants for ≥30 days with docs).
Scope 2/2 Clear boundaries with 6 specific non-goals explaining what's deferred and why (InfiniBand/NVLink implementation, VPC resource, pool-based assignment, tenant-facing PKey resources, SR-IOV east-west, scope changes). Five real alternatives analyzed with detailed trade-offs — the strongest alternatives section among recent designs. PRD referenced via frontmatter. All relevant cross-cutting dimensions addressed or explicitly deferred: networking (core focus), provisioning (AAP Server Cluster roles), installation (CRD registration, Helm values, RBAC), E2E testing (netris-lab scenarios), documentation (auto-generated API ref, admin guide deferred), UI (CLI/API only Phase 1). All four personas covered in RBAC table with specific access levels.
Architecture 2/2 Follows all OSAC patterns: standard object shape (id, Metadata, Spec, Status), spec/status ownership correctly separated (user-controlled desired state vs system-controlled observed state), condition-based lifecycle (Ready, Provisioning), tenant isolation via osac.openshift.io/tenant annotation with OPA enforcement, typed EastWestConfig messages (not maps), NetworkClass pluggable architecture. Owner-reference explicitly addressed as N/A with sound reasoning (association, not ownership). Dependencies enumerated across fulfillment-service, osac-operator, osac-aap (existing PR #447), and osac-installer. Terminology (N-S vs E-W, FabricDomain vs VirtualNetwork) defined upfront and used consistently. Additive changes with clear upgrade/downgrade and version skew strategies.

Verdict: A strong, comprehensive design that follows all OSAC architectural patterns, provides deep technical detail (proto schemas, SQL DDL, validation rules with error codes, failure handling matrix), and includes an unusually thorough alternatives analysis with five options evaluated.

Feedback: The SignalFabricDomain RPC is declared in the gRPC service but never described anywhere in the design — add request/response types, the use case (e.g., trigger re-reconciliation), and which persona invokes it, or remove it if it's not needed for Phase 1. Consider explicitly positioning FabricDomain within the two-manager model from the unified networking decisions (fabricManager handles the Netris/UFM backend; k8sManager is N/A for bare-metal Phase 1) to help reviewers connect this design to the established networking architecture. The Phase 1 limitation of no server overlap validation across FabricDomains is well-documented, but consider adding a brief note on the blast radius — what happens to existing workloads if Netris accepts overlapping servers and applies conflicting port configs.

Critical (0)

None.

Important (2)

  1. SignalFabricDomain RPC is declared in the gRPC service definition (proto schema) but has no description, request/response message types, workflow, use case, or test coverage anywhere in the design. Undocumented API surface will generate reviewer questions and could ship with undefined semantics.
  2. Server overlap across FabricDomains is deferred to Phase 2 with 'admin is trusted,' but the failure handling table notes Netris may accept overlapping servers — the blast radius of that acceptance (conflicting port configs, silent data-plane crosstalk) is not characterized. Even if validation is deferred, documenting the worst-case outcome helps ops teams.

Suggestions (3)

  1. Explicitly reference the two-manager model from networking-decisions.md to connect FabricDomain to the unified networking architecture (fabricManager handles Netris/UFM backend for FabricDomain; k8sManager is not involved in bare-metal Phase 1).
  2. The Phase 1 workflow restricts FabricDomain creation to Cloud Infrastructure Admin. Consider noting whether Tenant Admin self-service creation is a Phase 2 goal, as AI tenants with frequent job-scoped fabric needs may find the admin bottleneck limiting.
  3. The database schema uses TEXT for the type column rather than a constrained enum. Consider adding a CHECK constraint or documenting why application-level validation is preferred for this field.

Structural notes (0)

None.


Review cost

Model: claude-opus-4-6
Cost: $0.5758
Tokens: 810 in / 5.6k out
Cache: 128.7k read
Active time: 2m 3s
API calls: 0

@danmanor danmanor added the lgtm label Aug 27, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 6635484 into osac-project:main Aug 27, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants