Skip to content

feat: add NSO network lifecycle - #22

Merged
scotwells merged 3 commits into
mainfrom
codex/fleet-nso-network
Nov 5, 2026
Merged

scotwells merged 3 commits into
mainfrom
codex/fleet-nso-network

Conversation

@scotwells

Copy link
Copy Markdown
Contributor

Summary

  • add an NSO-independent network lifecycle contract and an unwired NSO adapter pinned to the reviewed NSO commit
  • retain exact network, authorization, object-guard, UID, observation, and delete authority before effects
  • gate installation, cleanup, public readiness, and finalizer release on fresh verified network evidence
  • align Fleet request/CRD cardinality with NSO and keep internal identities out of public status

Validation

  • go test -race ./...
  • go vet ./...
  • go mod tidy -diff
  • focused crash/concurrency tests repeated 30x
  • CRD YAML and kustomize build validation
  • git diff --check
  • adversarial correctness, security, and PR-scope reviews: no P0/P1/P2 findings

Scope

This stack is intentionally an unwired library/adapter increment. Production caller-preserving authorization, durable object-guard storage, manager watches, Milo integration, and deployment wiring remain in later stacked PRs.

@scotwells
scotwells requested review from ecv and kevwilliams November 4, 2026 02:59
ecv
ecv previously approved these changes Nov 4, 2026

@ecv ecv 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.

Approve.

Adds the NSO network lifecycle adapter with caller-preserving authorization, guard-protected NetworkInterfaceClaim create/recover, and fenced release. Nothing here deploys; the adapter only runs behind interfaces (UseAuthorizer, ObjectGuard, AuthorityVerifier) that have no production implementation yet, and New refuses nil ones.

  • Preflight rejects any NetworkNS that differs from the claim namespace (internal/network/nso/adapter.go), so a claim cannot reach a Network in another tenant namespace, and passes the initiating PrincipalUID to the authorizer rather than the controller identity.
  • Ensure and Release bind each NSO claim to claim UID, binding ID, plan digest, interface name and a guard token (claimMatches), and refuse a pre-existing object with a different UID or token (ErrObjectConflict). A name squatted by someone else cannot be adopted.
  • The CRD change only adds maxItems caps (2 families, 4 address classes) to a v1alpha1 CRD nothing consumes yet.

Follow-ups:

  • Preflight reads the Network with the controller identity before asking the authorizer, so NotFound versus ErrAuthorizationDenied can tell a caller whether a Network name exists. Authorize first, or return one error for both.
  • The UseAuthorizer, ObjectGuard and AuthorityVerifier implementations are the real security boundary and are not in this stack yet. Give them a tracking issue so the fail-closed constructor is not wired to permissive stubs.

@ecv
ecv requested a review from andrewb3000 November 5, 2026 04:25
andrewb3000
andrewb3000 previously approved these changes Nov 5, 2026

@kevwilliams kevwilliams 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.

Hold: any edit to a Network wedges every existing allocation on it.

  • Ensure rejects a Network whose generation moved since Preflight, even after the claim exists. NSO's Network spec (MTU, DNS, egress) is mutable, so one edit makes Ensure return stale forever, and ReconcileNetwork saves that empty observation, dropping addresses from status and blocking every later Install. The retry digest omits the generation, so nothing re-plans.
  • Fix: check generation only before create, and keep the last good observation on error.
  • Test: bump generation after Programmed; the existing test bumps it only before create.

@scotwells
scotwells changed the base branch from codex/fleet-core-lifecycle to main November 5, 2026 20:12
@scotwells
scotwells dismissed stale reviews from andrewb3000 and ecv November 5, 2026 20:12

The base branch was changed.

@scotwells
scotwells requested review from ecv and kevwilliams November 5, 2026 20:12
@scotwells

Copy link
Copy Markdown
Contributor Author

Addressed in 4b0330f. Ensure now requires the retained Network generation and current Ready evidence only before creating a NetworkInterfaceClaim; an existing exact guarded claim continues across mutable Network generations while UID, deletion, guard, claim identity, and external authority remain verified. ReconcileNetwork now preserves the last Programmed observation and addresses when a refresh errors, while retaining complete lifecycle progress. Added regressions for a generation bump after Programmed and for preservation of the last good observation on refresh failure. Verified with go test ./..., go test -race ./internal/network/nso ./internal/controller, and git diff --check.

@kevwilliams kevwilliams 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.

Verified the Network generation and readiness check now runs only before claim create, a failed refresh keeps the last Programmed observation, and both new tests cover the reported sequence.

@scotwells
scotwells merged commit da3c3e5 into main Nov 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants