feat(api): add NetworkEgressPolicy and NetworkGatewayStatus.EgressAddress - #15
Merged
Conversation
…ress Phase A of datum-cloud/enhancements#865 (NAT masquerade egress for the edge gateway), per docs/plans/865-edge-gateway-nat66-egress.md in the galactic repo. NetworkEgressPolicy is a new namespaced, tenant-writable type enabling internet egress for a single VPC/VPCAttachment. Unlike NetworkRule it carries no VIP/backend/port: egress is on or off for a (vpcRef, vpcAttachmentRef) pair, existence-implies-enabled, mirroring how sparse NetworkRuleSpec already keeps those two fields as opaque, unvalidated-by-this-API identifiers gated by the same ownership-verification admission webhook. NetworkGatewayStatus gains EgressAddress, the publicly-routable masquerade SNAT source, populated and advertised the same way SRv6Address already is. Both fields are optional independently — a gateway node not offering egress is a valid deployment. Regenerated deepcopy methods, CRD manifests, and API docs via `task generate`. Scoped .crd-ref-docs.yaml so NetworkEgressPolicy only renders into gateway.md, matching how NetworkGateway/NetworkRule are already excluded from bgp.md.
scotwells
previously approved these changes
Aug 13, 2026
…Status.AssignedGatewayNode Phase D of #865, per docs/plans/865-edge-gateway-nat66-egress.md §4.4/§4.5. Neither field is in the plan's own text -- both surfaced as necessary once Phase D's controller was actually implemented: - EgressSID publishes a gateway node's egress_sid locator the same way SRv6Address/EgressAddress already are. Without it, no compute node has a kernel route to encapsulate toward: RouteEgressAdd requires one to already exist via BGP/EVPN, the same requirement SRv6Address's own advertisement already satisfies. - AssignedGatewayNode mirrors NetworkRuleStatus.PrimaryNode's set-once contract for the identical reason: a route reconciler that recomputes AssignPrimaryNode on every pass would flap a tenant's egress node whenever the gateway-node pool changes, exactly what PrimaryNode's own doc comment warns against for ingress.
Collaborator
Author
|
Added in a follow-up commit (Phase D, #865): |
scotwells
approved these changes
Aug 14, 2026
privateip
added a commit
to datum-cloud/galactic
that referenced
this pull request
Aug 14, 2026
datum-cloud/network#15 (NetworkEgressPolicy, NetworkGatewayStatus. EgressAddress) merged to main at 96677d6. Replace the local ../network replace directive from 35d009c with a real pseudo-version pinned to that commit; drop the replace now that it's no longer dev-only. No tag has been cut yet, so this is still a pseudo-version rather than a semver tag — bump to a tag once one exists. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
privateip
added a commit
to datum-cloud/galactic
that referenced
this pull request
Aug 14, 2026
Phase E of #865, per docs/plans/865-edge-gateway-nat66-egress.md §6/§8. Fixed first, found by trying to wire this up: config/gateway/rbac.yaml and config/router/rbac.yaml never granted access to networkegresspolicies (or, for galactic-router, networkgateways) -- Phase D's two new reconcilers would hit RBAC-forbidden errors in any real deployment, not just this lab. Lab wiring: - GALACTIC_GATEWAY_EGRESS_ADDRESS/_SID on both gateway nodes. egress_sid reuses each node's own ingress locator (only the top 64 bits are ever compared). masq_addr is a new, dedicated loopback address, not a reuse of the node's existing BGP-session address -- reusing it would make the fail-closed egress-return dispatch also claim and drop the node's own inbound BGP TCP traffic. - NetworkEgressPolicy for ns10's iad attachment (not ns60, the ingress canary -- ns60 runs nginx, no ping; ns10 runs netshoot). Only ns10's iad pod can egress in this lab: each site is a separate Kind cluster, so NetworkGateway/NetworkEgressPolicy only exist where iad's own cluster can see them. - scripts/verify-egress.sh + task verify:egress: pings tr1's own loopback (already BGP-announced, outside any SRv6/uSID space) from ns10's iad pod. - deploy-system.sh's CRD-install list was missing networkegresspolicies entirely -- fixed. Telemetry/quota: confirmed, not added. edgemetrics.Collector iterates DropReasonCount/DropReasonNames generically, so Phase B's new egress drop reasons are already exposed with no changes here. QuotaEnforcer/TelemetryEmitter stay Noop per the plan's own Phase E deferral. Not run live: bringing up three Kind clusters plus the full FRR/BGP mesh is a multi-minute operation not attempted in this session. Validated instead with `kubectl kustomize` against config/gateway/, config/router/, and (after simulating the deploy-time docker cp step) the affected lab overlays -- all build clean. The lab also can't fully deploy until datum-cloud/network#15 merges and tags: deploy- system.sh pulls CRDs from the tagged upstream repo, not this session's local checkout.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase A of datum-cloud/enhancements#865 (NAT masquerade egress for the edge gateway), per
docs/plans/865-edge-gateway-nat66-egress.md§4.1 in the galactic repo.NetworkEgressPolicytype — namespaced, tenant-writable, gated by the same ownership-verification admission webhookNetworkRulealready requires. Carries onlyvpcRef/vpcAttachmentRef(existence-implies-enabled) — no VIP/backend/port, since egress destinations are arbitrary internet addresses, not a pre-configured backend list.NetworkGatewayStatus.EgressAddress— the publicly-routable masquerade SNAT source, populated/advertised the same waySRv6Addressalready is. Optional independently ofSRv6Address; a gateway node not offering egress leaves it empty.task generate..crd-ref-docs.yamlso the new type renders only intogateway.md, matching howNetworkGateway/NetworkRuleare already excluded frombgp.md.Testing
go build ./...,go vet ./...,go test ./api/...— all pass.task lint— 0 issues.Notes for reviewers
config/crd/kustomization.yamlwas already missingbgpcommunitysets,bgpprefixlists,networkgateways, andnetworkrulesbefore this PR — pre-existing gap, not introduced here. I only added my own new entry; happy to fix the rest in a follow-up if wanted.datum-cloud/galactic's consuming PR can drop its temporary localreplacedirective — see that PR's description.🤖 Generated with Claude Code