photoncloud-monorepo/novanet/T022-S2-IMPLEMENTATION-SUMMARY.md
centra a7ec7e2158 Add T026 practical test + k8shost to flake + workspace files
- Created T026-practical-test task.yaml for MVP smoke testing
- Added k8shost-server to flake.nix (packages, apps, overlays)
- Staged all workspace directories for nix flake build
- Updated flake.nix shellHook to include k8shost

Resolves: T026.S1 blocker (R8 - nix submodule visibility)
2025-12-09 06:07:50 +09:00

5.7 KiB

T022.S2: Gateway Router + SNAT Implementation Summary

Implementation Complete

Files Modified

  1. /home/centra/cloud/novanet/crates/novanet-server/src/ovn/mock.rs (259 lines)

    • Added MockRouter struct to track router state
    • Added MockRouterPort struct to track router port attachments
    • Added MockSnatRule struct to track SNAT rules
    • Extended MockOvnState with router management fields
    • Implemented router lifecycle methods:
      • create_router() - Creates router and returns UUID
      • delete_router() - Deletes router and cascades cleanup
      • add_router_port() - Attaches router to logical switch
      • configure_snat() - Adds SNAT rule
    • Added convenience test methods:
      • router_exists()
      • router_port_exists()
      • snat_rule_exists()
      • get_router_port_count()
  2. /home/centra/cloud/novanet/crates/novanet-server/src/ovn/client.rs (946 lines)

    • Added router management methods to OvnClient:
      • create_logical_router(name: &str) -> Result<String>
      • delete_logical_router(router_id: &str) -> Result<()>
      • add_router_port(router_id, switch_id, cidr, mac) -> Result<String>
      • configure_snat(router_id, external_ip, logical_ip_cidr) -> Result<()>
    • All methods support both Mock and Real OVN modes
    • Router port attachment handles both router-side and switch-side port creation

Test Results

39/39 tests passing (including 7 new router tests):

  1. test_router_create_and_delete - Router lifecycle
  2. test_router_port_attachment - Port attachment to switch
  3. test_snat_configuration - SNAT rule configuration
  4. test_router_deletion_cascades - Cascade cleanup on router deletion
  5. test_multiple_router_ports - Multiple switch attachments
  6. test_full_vpc_router_snat_workflow - Complete VPC → Router → SNAT flow
  7. test_multiple_snat_rules - Multiple SNAT rules per router

All existing tests remain passing (32 non-router tests).

Example OVN Commands

1. Create Logical Router

# Create router
ovn-nbctl lr-add vpc-router

# Query router UUID (for tracking)
ovn-nbctl --columns=_uuid --bare find Logical_Router name=vpc-router
# Output: e.g., "router-f3b1a2c4-5d6e-7f8a-9b0c-1d2e3f4a5b6c"

2. Add Router Port (Connect Router to VPC Switch)

# Create logical router port on the router side
ovn-nbctl lrp-add vpc-router \
    rtr-port-a1b2c3d4 \
    02:00:00:00:00:01 \
    10.0.0.1/24

# Create corresponding switch port on the switch side
ovn-nbctl lsp-add vpc-switch-id lsp-rtr-a1b2c3d4

# Set the switch port type to "router"
ovn-nbctl lsp-set-type lsp-rtr-a1b2c3d4 router

# Set addresses to "router" (special keyword)
ovn-nbctl lsp-set-addresses lsp-rtr-a1b2c3d4 router

# Link the switch port to the router port
ovn-nbctl lsp-set-options lsp-rtr-a1b2c3d4 router-port=rtr-port-a1b2c3d4

3. Configure SNAT (Source NAT for Outbound Traffic)

# Map internal subnet to external IP for outbound connections
ovn-nbctl lr-nat-add vpc-router snat 203.0.113.10 10.0.0.0/24

# Multiple SNAT rules can be added for different subnets
ovn-nbctl lr-nat-add vpc-router snat 203.0.113.11 10.1.0.0/24

4. Delete Logical Router

# Delete router (automatically cleans up associated ports and NAT rules)
ovn-nbctl lr-del vpc-router

Complete VPC + Router + SNAT Workflow Example

# Step 1: Create VPC logical switch
ovn-nbctl ls-add vpc-10.0.0.0-16
ovn-nbctl set Logical_Switch vpc-10.0.0.0-16 other_config:subnet=10.0.0.0/16

# Step 2: Create logical router for external connectivity
ovn-nbctl lr-add vpc-router-main
# Returns UUID: router-abc123...

# Step 3: Connect router to VPC switch (gateway interface)
# Router port with gateway IP 10.0.0.1/24
ovn-nbctl lrp-add router-abc123 rtr-port-gw 02:00:00:00:00:01 10.0.0.1/24

# Switch side connection
ovn-nbctl lsp-add vpc-10.0.0.0-16 lsp-rtr-gw
ovn-nbctl lsp-set-type lsp-rtr-gw router
ovn-nbctl lsp-set-addresses lsp-rtr-gw router
ovn-nbctl lsp-set-options lsp-rtr-gw router-port=rtr-port-gw

# Step 4: Configure SNAT for outbound internet access
# All traffic from 10.0.0.0/24 subnet appears as 203.0.113.10
ovn-nbctl lr-nat-add router-abc123 snat 203.0.113.10 10.0.0.0/24

# Step 5: (Optional) Add default route for external traffic
# ovn-nbctl lr-route-add router-abc123 0.0.0.0/0 <external-gateway-ip>

Traffic Flow Example

With this configuration:

  1. VM in VPC (10.0.0.5) sends packet to internet (8.8.8.8)
  2. Default route sends packet to gateway (10.0.0.1 - router port)
  3. Router receives packet on internal interface
  4. SNAT rule translates source IP: 10.0.0.5203.0.113.10
  5. Router forwards packet to external network with public IP
  6. Return traffic is automatically un-NAT'd and routed back to 10.0.0.5

Key Design Decisions

  1. Router ID Format: Mock mode uses router-<uuid> format for consistency
  2. Port Naming:
    • Router ports: rtr-port-<uuid>
    • Switch router ports: lsp-rtr-<uuid>
  3. MAC Address: Caller-provided for flexibility (e.g., 02:00:00:00:00:01)
  4. Cascade Deletion: Deleting router automatically cleans up ports and SNAT rules
  5. Mock Support: Full mock implementation enables testing without OVN daemon

Integration Points

Router functionality is now available for:

  • VPC service integration (future work in T022.S5)
  • External network connectivity enablement
  • Inter-VPC routing (with multiple router ports)
  • NAT/PAT services (SNAT implemented, DNAT can be added)

Next Steps (T022.S5)

  • Wire router creation into VPC lifecycle in /home/centra/cloud/novanet/crates/novanet-server/src/services/vpc.rs
  • Add API endpoints for explicit router management
  • Consider automatic gateway IP allocation
  • Add integration tests with real OVN (requires OVN daemon)