Skip to content

CRD Reference

NovaEdge uses 12 Custom Resource Definitions (CRDs) to configure load balancing, routing, policies, and SD-WAN.

CRD Overview

flowchart TB
    subgraph Cluster["Cluster Management"]
        NEC["NovaEdgeCluster<br/>Operator-managed deployment"]
        NERC["NovaEdgeRemoteCluster<br/>Multi-cluster registration"]
        FED["NovaEdgeFederation<br/>Active-active controllers"]
    end

    subgraph DataPlane["Data Plane Configuration"]
        VIP["ProxyVIP<br/>Virtual IP definition"]
        IPPool["ProxyIPPool<br/>IP address pool management"]
        GW["ProxyGateway<br/>Listeners (ports/protocols)"]
        RT["ProxyRoute<br/>Routing rules"]
        BE["ProxyBackend<br/>Upstream services"]
        POL["ProxyPolicy<br/>Rate limit, CORS, JWT, etc."]
    end

    subgraph SDWAN["SD-WAN"]
        WL["ProxyWANLink<br/>WAN link management"]
        WP["ProxyWANPolicy<br/>Path selection policies"]
    end

    NEC --> GW
    NEC --> VIP
    NERC --> NEC
    FED --> NEC

    IPPool --> VIP
    VIP --> GW
    GW --> RT
    RT --> BE
    RT --> POL
    GW --> POL

    WP --> WL

    style Cluster fill:#e6f3ff
    style DataPlane fill:#fff5e6
    style SDWAN fill:#e8f5e9

CRD Relationships

flowchart LR
    subgraph Input["Traffic Input"]
        Client((Client))
    end

    subgraph VIPLayer["VIP Layer"]
        VIP["ProxyVIP<br/>192.168.1.100"]
    end

    subgraph GatewayLayer["Gateway Layer"]
        GW["ProxyGateway<br/>:80 HTTP<br/>:443 HTTPS"]
    end

    subgraph RoutingLayer["Routing Layer"]
        RT1["ProxyRoute<br/>api.example.com"]
        RT2["ProxyRoute<br/>web.example.com"]
    end

    subgraph PolicyLayer["Policy Layer"]
        POL1["RateLimit"]
        POL2["JWT Auth"]
        POL3["CORS"]
    end

    subgraph BackendLayer["Backend Layer"]
        BE1["ProxyBackend<br/>api-service"]
        BE2["ProxyBackend<br/>web-service"]
    end

    Client --> VIP
    IPPool --> VIP
    VIP --> GW
    GW --> RT1
    GW --> RT2
    RT1 --> POL1
    RT1 --> POL2
    RT2 --> POL3
    RT1 --> BE1
    RT2 --> BE2

    style VIPLayer fill:#90EE90
    style GatewayLayer fill:#ADD8E6
    style RoutingLayer fill:#FFE4B5
    style PolicyLayer fill:#DDA0DD
    style BackendLayer fill:#F0E68C

NovaEdgeCluster

Defines a complete NovaEdge deployment managed by the operator.

apiVersion: novaedge.io/v1alpha1
kind: NovaEdgeCluster
metadata:
  name: novaedge
  namespace: novaedge-system
spec:
  # Version of NovaEdge to deploy
  version: "v0.1.0"

  # Image repository (optional)
  imageRepository: ghcr.io/piwi3910/novaedge
  imagePullPolicy: IfNotPresent

  # Controller configuration
  controller:
    replicas: 1
    leaderElection: true
    grpcPort: 9090
    metricsPort: 8080
    healthPort: 8081
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"
      limits:
        cpu: "500m"
        memory: "512Mi"

  # Agent DaemonSet configuration
  agent:
    hostNetwork: true
    httpPort: 80
    httpsPort: 443
    metricsPort: 9090
    healthPort: 8080
    vip:
      enabled: true
      mode: L2  # L2, BGP, or OSPF
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"

  # Web UI configuration (optional)
  webUI:
    enabled: true
    replicas: 1
    port: 9080
    readOnly: false
    service:
      type: ClusterIP
    prometheusEndpoint: "http://prometheus:9090"

  # Observability configuration
  observability:
    metrics:
      enabled: true
      serviceMonitor:
        enabled: true
        interval: "30s"
    tracing:
      enabled: true
      endpoint: "jaeger-collector:4317"
      samplingRate: 10
    logging:
      level: info
      format: json

NovaEdgeCluster Fields

Field Type Required Description
spec.version string Yes NovaEdge version to deploy
spec.imageRepository string No Container image repository
spec.imagePullPolicy string No Image pull policy
spec.controller object Yes Controller deployment configuration
spec.agent object Yes Agent DaemonSet configuration
spec.webUI object No Web UI deployment configuration
spec.tls object No Internal TLS configuration
spec.observability object No Metrics, tracing, logging config

Controller Configuration

Field Type Default Description
replicas int 1 Number of controller replicas
leaderElection bool true Enable leader election for HA
grpcPort int 9090 gRPC config server port
metricsPort int 8080 Prometheus metrics port
healthPort int 8081 Health probe port
resources object - Resource requirements
nodeSelector map - Node selector
tolerations array - Pod tolerations
affinity object - Pod affinity rules

Agent Configuration

Field Type Default Description
hostNetwork bool true Enable host networking
httpPort int 80 HTTP traffic port
httpsPort int 443 HTTPS traffic port
metricsPort int 9090 Prometheus metrics port
healthPort int 8080 Health probe port
vip.enabled bool true Enable VIP management
vip.mode string L2 VIP mode: L2, BGP, OSPF
vip.interface string - Network interface (L2 mode)
vip.bgp object - BGP configuration
updateStrategy object - DaemonSet update strategy

NovaEdgeCluster Status

status:
  phase: Running
  observedGeneration: 1
  version: v0.1.0
  conditions:
    - type: Ready
      status: "True"
      reason: AllComponentsReady
    - type: ControllerReady
      status: "True"
    - type: AgentReady
      status: "True"
  controller:
    ready: true
    replicas: 1
    readyReplicas: 1
  agent:
    ready: true
    replicas: 3
    readyReplicas: 3

NovaEdgeRemoteCluster

Represents a remote/edge cluster in a hub-spoke multi-cluster deployment. Created in the hub cluster to register and monitor remote clusters.

apiVersion: novaedge.io/v1alpha1
kind: NovaEdgeRemoteCluster
metadata:
  name: edge-west-1
  namespace: novaedge-system
spec:
  # Unique cluster identifier
  clusterName: edge-west-1

  # Geographic location
  region: us-west
  zone: us-west-2a

  # Additional labels
  labels:
    environment: production
    tier: edge

  # Connection to hub controller
  connection:
    mode: Direct  # Direct or Tunnel
    controllerEndpoint: controller.novaedge-system.svc.cluster.local:9090
    reconnectInterval: 30s
    timeout: 10s
    tls:
      enabled: true
      caSecretRef:
        name: novaedge-ca
        namespace: novaedge-system
      serverName: novaedge-controller

  # Agent configuration for this cluster
  agent:
    version: "v0.1.0"  # Override version
    nodeSelector:
      node-role.kubernetes.io/edge: "true"
    vip:
      enabled: true
      mode: L2

  # Routing configuration
  routing:
    enabled: true
    priority: 100
    weight: 100
    localPreference: true
    allowCrossClusterTraffic: true

  # Health check configuration
  healthCheck:
    enabled: true
    interval: 30s
    timeout: 10s
    healthyThreshold: 2
    unhealthyThreshold: 3
    failoverEnabled: true

NovaEdgeRemoteCluster Fields

Field Type Required Description
spec.clusterName string Yes Unique identifier for the remote cluster
spec.region string No Geographic region
spec.zone string No Availability zone
spec.labels map No Additional labels for the cluster
spec.connection object Yes Connection configuration
spec.agent object No Agent configuration override
spec.routing object No Routing configuration
spec.healthCheck object No Health check configuration
spec.paused bool No Suspend reconciliation

Connection Configuration

Field Type Default Description
mode string Direct Connection mode: Direct or Tunnel
controllerEndpoint string Required Hub controller gRPC endpoint
reconnectInterval duration 30s Reconnection interval
timeout duration 10s Connection timeout
tls.enabled bool true Enable mTLS
tls.caSecretRef object - CA certificate secret reference
tls.clientCertSecretRef object - Client certificate secret reference
tls.serverName string - Expected server name for TLS
tls.insecureSkipVerify bool false Skip TLS verification
tunnel object - Tunnel configuration (when mode=Tunnel)

Routing Configuration

Field Type Default Description
enabled bool true Enable routing to/from this cluster
priority int 100 Routing priority (lower = higher priority)
weight int 100 Traffic weight for weighted routing
localPreference bool true Prefer local backends within cluster
allowCrossClusterTraffic bool true Allow cross-cluster traffic routing
endpoints object - Endpoint selection filters

Health Check Configuration

Field Type Default Description
enabled bool true Enable health checking
interval duration 30s Health check interval
timeout duration 10s Health check timeout
healthyThreshold int 2 Consecutive successes for healthy
unhealthyThreshold int 3 Consecutive failures for unhealthy
failoverEnabled bool true Enable automatic failover

NovaEdgeRemoteCluster Status

status:
  phase: Connected
  observedGeneration: 1
  conditions:
    - type: Ready
      status: "True"
      reason: Connected
    - type: AgentsHealthy
      status: "True"
  connection:
    connected: true
    activeConnections: 3
    lastConnected: "2024-01-15T10:30:00Z"
    latency: "15ms"
  agents:
    total: 3
    ready: 3
    healthy: 3
    nodes:
      - name: edge-node-1
        ready: true
        ip: 10.1.0.10
        vips: ["192.168.1.100"]
      - name: edge-node-2
        ready: true
        ip: 10.1.0.11
  lastHeartbeat: "2024-01-15T12:00:00Z"
  lastConfigSync: "2024-01-15T11:55:00Z"
  version: v0.1.0

Remote Cluster Phases

Phase Description
Pending Remote cluster is pending connection
Connecting Connection is being established
Connected Remote cluster is connected and healthy
Degraded Some agents are unhealthy
Disconnected No active connections from remote cluster
Failed Remote cluster configuration failed

NovaEdgeFederation

Configures active-active federation between multiple NovaEdge controllers for multi-datacenter deployments with state synchronization and split-brain protection.

apiVersion: novaedge.io/v1alpha1
kind: NovaEdgeFederation
metadata:
  name: production-federation
  namespace: novaedge-system
spec:
  # Unique federation identifier
  federationID: prod-fed-01

  # This controller's identity
  localMember:
    name: controller-dc1
    region: us-west
    zone: us-west-2a
    endpoint: controller-dc1.novaedge.example.com:9090

  # Peer controllers
  members:
    - name: controller-dc2
      endpoint: controller-dc2.novaedge.example.com:9090
      region: us-east
      zone: us-east-1a
      tls:
        enabled: true
        caSecretRef:
          name: novaedge-federation-ca
        clientCertSecretRef:
          name: novaedge-federation-client-cert
      priority: 100

  # Synchronization settings
  sync:
    interval: 5s
    timeout: 30s
    batchSize: 100
    compression: true

  # Conflict resolution
  conflictResolution:
    strategy: LastWriterWins  # LastWriterWins, Merge, Manual
    vectorClocks: true
    tombstoneTTL: 24h

  # Health checking
  healthCheck:
    interval: 10s
    timeout: 5s
    failureThreshold: 3
    successThreshold: 1

  # Split-brain detection and protection
  splitBrain:
    enabled: true
    partitionTimeout: 30s
    quorumMode: AgentAssisted  # Controllers or AgentAssisted
    quorumRequired: true
    fencingEnabled: true
    healingGracePeriod: 5s
    autoResolveOnHeal: true
    agentQuorum:
      controllerWeight: 10
      agentWeight: 1
      minAgentsForQuorum: 1

NovaEdgeFederation Fields

Field Type Required Description
spec.federationID string Yes Unique federation identifier
spec.localMember object Yes This controller's identity
spec.members array No Peer controller configurations
spec.sync object No Synchronization settings
spec.conflictResolution object No Conflict resolution settings
spec.healthCheck object No Health check configuration
spec.splitBrain object No Split-brain detection settings
spec.paused bool No Suspend federation sync

Split-Brain Configuration

Field Type Default Description
enabled bool true Enable split-brain detection
partitionTimeout duration 30s Time before confirming partition
quorumMode string Controllers Controllers or AgentAssisted
quorumRequired bool false Require quorum for writes
fencingEnabled bool false Block writes during partition
healingGracePeriod duration 5s Grace period after partition heals
autoResolveOnHeal bool true Auto-resolve conflicts on heal

Agent-Assisted Quorum Configuration

For 2-datacenter deployments, agent-assisted quorum enables split-brain prevention:

Field Type Default Description
agentQuorum.controllerWeight int 10 Voting weight per controller
agentQuorum.agentWeight int 1 Voting weight per agent
agentQuorum.minAgentsForQuorum int 1 Minimum agents required

NovaEdgeFederation Status

status:
  phase: Healthy
  observedGeneration: 1
  conditions:
    - type: Ready
      status: "True"
      reason: AllPeersHealthy
    - type: Synced
      status: "True"
  members:
    - name: controller-dc2
      healthy: true
      lastSeen: "2024-01-15T12:00:00Z"
      lastSyncTime: "2024-01-15T11:59:55Z"
      syncLag: 5s
      vectorClock:
        controller-dc1: 150
        controller-dc2: 148
      agentCount: 5
  lastSyncTime: "2024-01-15T11:59:55Z"
  syncLag: 5s
  localVectorClock:
    controller-dc1: 150
    controller-dc2: 148
  conflictsPending: 0
  splitBrain:
    partitionState: Healthy
    haveQuorum: true
    writesFenced: false
    reachablePeers:
      - controller-dc2
    agentQuorumStatus:
      totalAgents: 10
      reachableAgents: 10
      ourVotes: 20
      totalVotes: 30
      quorumThreshold: 16

Federation Phases

Phase Description
Initializing Federation is starting up
Syncing Initial sync in progress
Healthy All members healthy and in sync
Degraded Some members unhealthy or out of sync
Partitioned Network partition detected

Partition States

State Description
Healthy All peers reachable
Suspected Some peers not responding
Confirmed Partition confirmed, fencing may be active
Healing Partition healing, reconciliation in progress

ProxyVIP

Defines a Virtual IP address for the load balancer. Supports IPv4, IPv6, and dual-stack configurations with optional BFD and IP pool allocation.

flowchart TB
    subgraph VIPModes["VIP Operating Modes"]
        subgraph L2Mode["L2 ARP/NDP Mode"]
            L2["Single active node<br/>GARP (IPv4) / NDP (IPv6)"]
        end
        subgraph BGPMode["BGP Mode"]
            BGP["All nodes announce<br/>ECMP routing<br/>Optional BFD"]
        end
        subgraph OSPFMode["OSPF/OSPFv3 Mode"]
            OSPF["LSA announcements<br/>L3 active-active<br/>Graceful restart"]
        end
    end

    style L2Mode fill:#90EE90
    style BGPMode fill:#FFE4B5
    style OSPFMode fill:#ADD8E6
apiVersion: novaedge.io/v1alpha1
kind: ProxyVIP
metadata:
  name: my-vip
spec:
  address: 10.200.0.100/32
  ipv6Address: "2001:db8::100/128"
  mode: BGP
  addressFamily: dual
  ports:
    - 80
    - 443
  bgpConfig:
    localAS: 65000
    routerID: "10.0.0.1"
    peers:
      - address: "10.0.0.254"
        as: 65001
  ospfConfig:
    routerID: "10.0.0.1"
    areaID: 0
    cost: 10
    helloInterval: 10
    deadInterval: 40
    authType: md5
    authKey: "mySecretKey"
    gracefulRestart: true
  bfd:
    enabled: true
    detectMultiplier: 3
    desiredMinTxInterval: "300ms"
    requiredMinRxInterval: "300ms"
    echoMode: false
  poolRef:
    name: main-vip-pool
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/loadbalancer: "true"

Spec Fields

Field Type Required Description
spec.address string No* IPv4 VIP address with CIDR (e.g., 10.200.0.100/32)
spec.ipv6Address string No* IPv6 VIP address with CIDR (e.g., 2001:db8::100/128)
spec.mode string Yes VIP mode: L2ARP, BGP, or OSPF
spec.addressFamily string No Address family: ipv4 (default), ipv6, or dual
spec.ports []int32 Yes Ports to bind on hostNetwork
spec.bgpConfig object BGP only BGP configuration (see below)
spec.ospfConfig object OSPF only OSPF configuration (see below)
spec.bfd object No BFD configuration for sub-second failover
spec.poolRef object No Reference to a ProxyIPPool for auto-allocation
spec.nodeSelector LabelSelector No Node selector for VIP placement
spec.healthPolicy object No Node health requirements

*At least one of address, ipv6Address, or poolRef must be specified.

BGP Config Fields

Field Type Required Description
bgpConfig.localAS int32 Yes Local BGP AS number (1-4294967295)
bgpConfig.routerID string Yes BGP router ID
bgpConfig.peers []object Yes BGP peer list (min 1)
bgpConfig.peers[].address string Yes Peer IP address (IPv4 or IPv6)
bgpConfig.peers[].as int32 Yes Peer AS number
bgpConfig.peers[].port int No Peer BGP port (default: 179)
bgpConfig.communities []string No BGP communities to attach
bgpConfig.localPreference int32 No Local preference for iBGP

OSPF Config Fields

Field Type Required Description
ospfConfig.routerID string Yes OSPF router ID
ospfConfig.areaID int32 No OSPF area ID (default: 0 = backbone)
ospfConfig.cost int32 No Route metric cost (default: 10)
ospfConfig.helloInterval int32 No Hello interval in seconds (default: 10)
ospfConfig.deadInterval int32 No Dead interval in seconds (default: 40)
ospfConfig.authType string No Authentication: none, plaintext, md5
ospfConfig.authKey string No Authentication key
ospfConfig.gracefulRestart bool No Enable graceful restart (default: false)

BFD Config Fields

Field Type Required Description
bfd.enabled bool No Enable BFD (default: false)
bfd.detectMultiplier int32 No Missed packets threshold (default: 3, range: 1-255)
bfd.desiredMinTxInterval string No Min TX interval (default: "300ms")
bfd.requiredMinRxInterval string No Min RX interval (default: "300ms")
bfd.echoMode bool No Enable echo mode (default: false)

Pool Ref Fields

Field Type Required Description
poolRef.name string Yes Name of the ProxyIPPool resource

Status Fields

Field Type Description
status.activeNode string Node currently owning the VIP (L2ARP mode)
status.announcingNodes []string Nodes announcing this VIP (BGP/OSPF)
status.allocatedAddress string Address allocated from pool
status.allocatedIpv6Address string IPv6 address allocated from pool
status.bfdSessionState string Current BFD session state
status.observedGeneration int64 Most recent generation observed
status.conditions []Condition Standard Kubernetes conditions

ProxyIPPool

Defines an IP address pool for automatic VIP address allocation.

apiVersion: novaedge.io/v1alpha1
kind: ProxyIPPool
metadata:
  name: main-vip-pool
spec:
  cidrs:
    - "10.200.0.0/24"
  addresses:
    - "10.200.1.100/32"
    - "10.200.1.200/32"
  autoAssign: true

Spec Fields

Field Type Required Description
spec.cidrs []string No* CIDR ranges for the pool
spec.addresses []string No* Explicit addresses (CIDR notation)
spec.autoAssign bool No Allow automatic allocation (default: false)

*At least one of cidrs or addresses must be specified.

Status Fields

Field Type Description
status.allocated int32 Number of allocated addresses
status.available int32 Number of available addresses
status.allocations []IPAllocation Current allocation details
status.allocations[].address string Allocated IP address
status.allocations[].vipRef string Name of the VIP using this address
status.allocations[].allocatedAt Time When the address was allocated
status.conditions []Condition Standard Kubernetes conditions

ProxyGateway

Defines listeners and binds them to a VIP.

apiVersion: novaedge.io/v1alpha1
kind: ProxyGateway
metadata:
  name: my-gateway
spec:
  # Reference to ProxyVIP
  vipRef: my-vip

  listeners:
    - name: http
      port: 80
      protocol: HTTP
      hostnames:
        - "*.example.com"

    - name: https
      port: 443
      protocol: HTTPS
      hostnames:
        - "*.example.com"
      tls:
        secretRef:
          name: my-tls-secret
          namespace: default
        minVersion: "TLS1.2"
        cipherSuites:
          - TLS_AES_128_GCM_SHA256
          - TLS_AES_256_GCM_SHA384

    - name: http3
      port: 443
      protocol: HTTP3
      hostnames:
        - "*.example.com"
      tls:
        secretRef:
          name: my-tls-secret
        minVersion: "TLS1.3"
      quic:
        maxIdleTimeout: "30s"
        maxBiStreams: 100
        enable0RTT: true

L4 Listener Examples

TCP and UDP listeners enable Layer 4 proxying for non-HTTP protocols:

apiVersion: novaedge.io/v1alpha1
kind: ProxyGateway
metadata:
  name: l4-gateway
spec:
  vipRef: my-vip
  listeners:
    # TCP listener for database traffic
    - name: mysql
      port: 3306
      protocol: TCP

    # UDP listener for DNS traffic
    - name: dns
      port: 53
      protocol: UDP

    # TLS passthrough listener (SNI-based routing)
    - name: tls-passthrough
      port: 8443
      protocol: TLS
      hostnames:
        - "api.example.com"
        - "*.internal.example.com"

For L4 proxying details, see Layer 4 TCP/UDP Proxying.

Fields

Field Type Required Description
spec.vipRef string Yes Reference to ProxyVIP name
spec.listeners array Yes List of listener configurations
spec.listeners[].name string Yes Unique listener name
spec.listeners[].port int32 Yes Port number
spec.listeners[].protocol string Yes Protocol: HTTP, HTTPS, HTTP3, TCP, TLS, UDP
spec.listeners[].hostnames array No Hostnames to match (wildcards supported)
spec.listeners[].tls object HTTPS/HTTP3 TLS configuration
spec.listeners[].quic object HTTP3 only QUIC configuration

ProxyRoute

Defines routing rules for traffic.

apiVersion: novaedge.io/v1alpha1
kind: ProxyRoute
metadata:
  name: my-route
spec:
  # Reference to parent gateway(s)
  parentRefs:
    - name: my-gateway
      namespace: default

  # Hostnames to match
  hostnames:
    - "api.example.com"

  # Routing rules
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api/v1
          headers:
            - name: X-API-Version
              value: v1
          method: GET

      # Backend reference
      backendRef:
        name: api-backend
        weight: 100

      # Request filters
      filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
              - name: X-Request-ID
                value: "${request_id}"
            set:
              - name: X-Forwarded-Proto
                value: https
            remove:
              - X-Legacy-Header

        - type: URLRewrite
          urlRewrite:
            path:
              type: ReplacePrefixMatch
              replacePrefixMatch: /v1

      # Response filters
      responseFilters:
        - type: ResponseHeaderModifier
          responseHeaderModifier:
            add:
              - name: X-Served-By
                value: novaedge
            remove:
              - Server

      # Policy references
      policyRefs:
        - name: rate-limit-policy

Match Types

Path Type Description Example
Exact Exact path match /api matches only /api
PathPrefix Prefix match /api matches /api, /api/v1, etc.
RegularExpression Regex match /api/v[0-9]+

Filter Types

Filter Type Description
RequestHeaderModifier Add, set, or remove request headers
ResponseHeaderModifier Add, set, or remove response headers
URLRewrite Rewrite URL path or hostname
RequestRedirect Redirect to different URL

ProxyBackend

Defines backend services and load balancing.

apiVersion: novaedge.io/v1alpha1
kind: ProxyBackend
metadata:
  name: my-backend
spec:
  # Reference to Kubernetes Service
  serviceRef:
    name: my-service
    port: 8080

  # Or static endpoints
  endpoints:
    - address: 10.0.0.1
      port: 8080
    - address: 10.0.0.2
      port: 8080

  # Load balancing policy
  lbPolicy: RoundRobin  # RoundRobin, P2C, EWMA, LeastConn, RingHash, Maglev

  # Health check configuration
  healthCheck:
    interval: 10s
    timeout: 5s
    healthyThreshold: 2
    unhealthyThreshold: 3
    httpHealthCheck:
      path: /health
      expectedStatuses:
        - 200
        - 204

  # Circuit breaker configuration
  circuitBreaker:
    maxConnections: 1000
    maxPendingRequests: 100
    maxRetries: 3
    consecutiveErrors: 5
    ejectionTime: 30s

  # Session affinity (sticky sessions)
  sessionAffinity:
    type: Cookie           # Cookie, Header, SourceIP
    cookieName: NOVAEDGE_AFFINITY
    cookieTTL: 30m
    cookiePath: /
    secure: true
    sameSite: Lax          # Strict, Lax, None

  # Connection pool configuration
  connectionPool:
    maxIdleConns: 100
    maxIdleConnsPerHost: 10
    idleConnTimeoutMs: 90000

Load Balancing Policies

flowchart LR
    subgraph Algorithms["Load Balancing Algorithms"]
        RR["RoundRobin<br/>Equal distribution"]
        P2C["P2C<br/>Best of 2 random"]
        EWMA["EWMA<br/>Latency-aware"]
        LC["LeastConn<br/>Connection-aware"]
        RH["RingHash<br/>Consistent hashing"]
        MAG["Maglev<br/>Google's algorithm"]
    end

    subgraph UseCase["Best For"]
        UC1["General purpose"]
        UC2["Low latency"]
        UC3["Latency-sensitive"]
        UC4["Session affinity"]
        UC5["High performance"]
    end

    RR --> UC1
    P2C --> UC2
    EWMA --> UC3
    RH --> UC4
    MAG --> UC5

    style Algorithms fill:#e6f3ff
Policy Description
RoundRobin Equal distribution across endpoints
P2C Power of Two Choices - pick best of 2 random
EWMA Exponentially Weighted Moving Average latency
RingHash Consistent hashing for session affinity
Maglev Google's Maglev consistent hashing

ProxyPolicy

Defines policies for rate limiting, security, and more.

flowchart TB
    subgraph PolicyTypes["Available Policy Types"]
        RL["RateLimit<br/>Token bucket<br/>Per-client/global"]
        CORS["CORS<br/>Cross-origin<br/>requests"]
        JWT["JWT Validation<br/>JWKS support<br/>Token verification"]
        IP["IP Filter<br/>Allow/deny lists<br/>CIDR support"]
        SEC["Security Headers<br/>HSTS, CSP<br/>XSS protection"]
        BA["BasicAuth<br/>HTTP Basic<br/>htpasswd support"]
        FA["ForwardAuth<br/>External auth<br/>delegation"]
        OIDC["OIDC<br/>OAuth2 SSO<br/>Keycloak support"]
    end

    subgraph Targets["Policy Targets"]
        GW["ProxyGateway<br/>(applies to all routes)"]
        RT["ProxyRoute<br/>(specific routes)"]
    end

    RL --> RT
    CORS --> RT
    JWT --> RT
    IP --> GW
    IP --> RT
    SEC --> GW
    BA --> RT
    FA --> RT
    OIDC --> RT

    style PolicyTypes fill:#DDA0DD
    style Targets fill:#fff5e6

Rate Limiting

apiVersion: novaedge.io/v1alpha1
kind: ProxyPolicy
metadata:
  name: rate-limit
spec:
  targetRef:
    kind: ProxyRoute
    name: my-route

  rateLimit:
    requestsPerSecond: 100
    burstSize: 150
    key: client_ip  # client_ip, header:<name>, cookie:<name>

CORS

apiVersion: novaedge.io/v1alpha1
kind: ProxyPolicy
metadata:
  name: cors-policy
spec:
  targetRef:
    kind: ProxyRoute
    name: my-route

  cors:
    allowOrigins:
      - "https://example.com"
      - "https://*.example.com"
    allowMethods:
      - GET
      - POST
      - PUT
      - DELETE
    allowHeaders:
      - Authorization
      - Content-Type
    exposeHeaders:
      - X-Request-ID
    maxAge: 86400
    allowCredentials: true

JWT Validation

apiVersion: novaedge.io/v1alpha1
kind: ProxyPolicy
metadata:
  name: jwt-policy
spec:
  targetRef:
    kind: ProxyRoute
    name: my-route

  jwt:
    issuer: https://auth.example.com
    audience:
      - api.example.com
    jwksUri: https://auth.example.com/.well-known/jwks.json
    headerName: Authorization
    headerPrefix: "Bearer "

IP Filtering

apiVersion: novaedge.io/v1alpha1
kind: ProxyPolicy
metadata:
  name: ip-filter
spec:
  targetRef:
    kind: ProxyRoute
    name: my-route

  ipFilter:
    allowList:
      - 10.0.0.0/8
      - 192.168.0.0/16
    denyList:
      - 10.0.0.5/32

BasicAuth

Field Type Required Description
spec.basicAuth.realm string No Authentication realm (default: "Restricted")
spec.basicAuth.secretRef.name string Yes Secret containing htpasswd data
spec.basicAuth.stripAuth bool No Strip Authorization header (default: true)

ForwardAuth

Field Type Required Description
spec.forwardAuth.address string Yes Auth service URL
spec.forwardAuth.authHeaders []string No Headers to forward
spec.forwardAuth.responseHeaders []string No Headers to copy from response
spec.forwardAuth.timeout string No Auth subrequest timeout (default: "5s")
spec.forwardAuth.cacheTTL string No Cache TTL (empty = no cache)

OIDC

Field Type Required Description
spec.oidc.provider string No Provider type: "generic" or "keycloak"
spec.oidc.issuerURL string Conditional OIDC issuer URL (auto-set for Keycloak)
spec.oidc.clientID string Yes OAuth2 client ID
spec.oidc.clientSecretRef.name string Yes Secret with "client-secret" key
spec.oidc.redirectURL string Yes OAuth2 callback URL
spec.oidc.scopes []string No OAuth2 scopes (default: openid, profile, email)
spec.oidc.sessionSecretRef.name string Yes Secret with "session-secret" key (32 bytes)
spec.oidc.forwardHeaders []string No Claims to forward as headers
spec.oidc.keycloak.serverURL string Yes (keycloak) Keycloak server URL
spec.oidc.keycloak.realm string Yes (keycloak) Keycloak realm
spec.oidc.keycloak.roleClaim string No Role claim path (default: realm_access.roles)
spec.oidc.keycloak.groupClaim string No Group claim path (default: groups)
spec.oidc.authorization.requiredRoles []string No Required roles
spec.oidc.authorization.requiredGroups []string No Required groups
spec.oidc.authorization.mode string No "any" (OR) or "all" (AND)

Security Headers

apiVersion: novaedge.io/v1alpha1
kind: ProxyPolicy
metadata:
  name: security-headers
spec:
  targetRef:
    kind: ProxyRoute
    name: my-route

  securityHeaders:
    hsts:
      enabled: true
      maxAgeSeconds: 31536000
      includeSubdomains: true
      preload: true
    xFrameOptions: DENY
    xContentTypeOptions: true
    referrerPolicy: strict-origin-when-cross-origin
    contentSecurityPolicy: "default-src 'self'"

Represents a WAN link for SD-WAN multi-link management. Tracks link properties, SLA thresholds, and observed quality metrics.

apiVersion: novaedge.io/v1alpha1
kind: ProxyWANLink
metadata:
  name: primary-fiber
spec:
  site: site-alpha
  interface: eth0
  provider: ISP-A
  bandwidth: "1Gbps"
  cost: 10
  role: primary
  sla:
    maxLatency: 50ms
    maxJitter: 10ms
    maxPacketLoss: 0.01
  tunnelEndpoint:
    publicIP: "203.0.113.1"
    port: 51820
Field Type Required Default Description
spec.site string Yes - Site name this WAN link belongs to
spec.interface string Yes - Network interface name (e.g., eth0, wg0)
spec.provider string Yes - ISP or WAN circuit provider name
spec.bandwidth string Yes - Provisioned bandwidth (e.g., 100Mbps, 1Gbps)
spec.cost int32 No 100 Administrative cost metric (lower is preferred)
spec.role string No primary Link role: primary, backup, or loadbalance
spec.sla object No - SLA thresholds for this link
spec.sla.maxLatency duration No - Maximum acceptable one-way latency
spec.sla.maxJitter duration No - Maximum acceptable jitter
spec.sla.maxPacketLoss float No - Maximum acceptable packet loss ratio (0.0-1.0)
spec.tunnelEndpoint object No - Public endpoint for tunnel establishment
spec.tunnelEndpoint.publicIP string Yes* - Publicly reachable IP address
spec.tunnelEndpoint.port int32 Yes* - UDP/TCP port for tunnel traffic (1-65535)

*Required when tunnelEndpoint is specified.

Field Type Description
status.phase string Current lifecycle phase of the WAN link
status.conditions []Condition Standard Kubernetes conditions
status.currentLatency float64 Most recently measured latency in milliseconds
status.currentPacketLoss float64 Most recently measured packet loss ratio (0.0-1.0)
status.healthy bool Whether the link currently meets its SLA thresholds
status.observedGeneration int64 Most recent generation observed by the controller
NAME              SITE         ROLE      PROVIDER   HEALTHY   AGE
primary-fiber     site-alpha   primary   ISP-A      true      5d

ProxyWANPolicy

Defines application-aware path selection rules for SD-WAN traffic. Matches traffic by host, path, or headers and routes it through the optimal WAN link.

apiVersion: novaedge.io/v1alpha1
kind: ProxyWANPolicy
metadata:
  name: voice-policy
spec:
  match:
    hosts:
      - "voice.example.com"
    paths:
      - "/api/voice"
    headers:
      X-Traffic-Class: voice
  pathSelection:
    strategy: lowest-latency
    failover: true
    dscpClass: EF

ProxyWANPolicy Spec Fields

Field Type Required Default Description
spec.match object No - Traffic matching criteria
spec.match.hosts []string No - Hostnames to match
spec.match.paths []string No - URL path prefixes to match
spec.match.headers map[string]string No - Header name-value pairs to match
spec.pathSelection object Yes - Path selection configuration
spec.pathSelection.strategy string Yes - Selection algorithm: lowest-latency, highest-bandwidth, most-reliable, lowest-cost
spec.pathSelection.failover bool No true Enable automatic failover when selected link fails SLA
spec.pathSelection.dscpClass string No - DSCP marking for matched traffic (e.g., EF, AF41, CS6)

ProxyWANPolicy Status Fields

Field Type Description
status.phase string Current lifecycle phase of the policy
status.conditions []Condition Standard Kubernetes conditions
status.selectionCount int64 Total number of path selections made using this policy
status.observedGeneration int64 Most recent generation observed by the controller
NAME            STRATEGY         DSCP   AGE
voice-policy    lowest-latency   EF     5d

Status Conditions

All NovaEdge CRDs include status conditions:

status:
  conditions:
    - type: Ready
      status: "True"
      reason: Valid
      message: Configuration is valid and applied
      lastTransitionTime: "2024-01-15T10:30:00Z"
  observedGeneration: 5

Common Condition Types

Type Description
Ready Resource is ready and configuration applied
Accepted Resource was accepted by controller
Programmed Configuration pushed to agents
Degraded Resource is partially working

Labels and Annotations

Common Labels

metadata:
  labels:
    app.kubernetes.io/name: my-app
    app.kubernetes.io/component: frontend
    novaedge.io/gateway: my-gateway

Annotations

metadata:
  annotations:
    # Custom logging level for this resource
    novaedge.io/log-level: debug

    # Skip validation (use with caution)
    novaedge.io/skip-validation: "true"

CompressionConfig

Response compression configuration, defined on ProxyGateway.spec.compression.

Field Type Required Default Description
enabled bool No false Enable response compression
minSize string No "1024" Minimum body size (bytes) before compression triggers
level int32 No 6 Compression level (gzip: 1-9, brotli: 0-11)
algorithms []string No ["gzip", "br"] Supported compression algorithms in preference order
excludeTypes []string No ["image/*", ...] Content type patterns to skip compression

RouteLimits

Per-route request size limits and timeouts, defined on ProxyRoute.spec.rules[].limits.

Field Type Required Default Description
maxRequestBodySize string No Gateway default Maximum request body size (e.g., "10Mi")
requestTimeout string No No timeout Total request timeout (e.g., "30s")
idleTimeout string No No timeout Connection idle timeout (e.g., "60s")

RouteBufferingConfig

Request/response buffering settings, defined on ProxyRoute.spec.rules[].buffering.

Field Type Required Default Description
request bool No false Buffer entire request body before forwarding
response bool No false Buffer entire response body before sending to client
maxSize string No No limit Maximum buffer size (e.g., "50Mi")

New Fields (v1alpha1)

ProxyGateway

Field Type Description
spec.loadBalancerClass string Load balancer class for multi-controller coexistence. Default: novaedge.io/proxy
spec.cache.enabled bool Enable HTTP response caching
spec.cache.maxSize string Maximum cache memory (e.g., 256Mi)
spec.cache.defaultTTL string Default cache TTL (e.g., 5m)
spec.cache.maxTTL string Maximum cache TTL (e.g., 1h)
spec.cache.maxEntrySize string Maximum single entry size (e.g., 1Mi)

ProxyRoute

Field Type Description
spec.rules[].mirror.backendRef BackendRef Backend to mirror traffic to
spec.rules[].mirror.percentage int (0-100) Percentage of requests to mirror (default: 100)

Controller Flags

Flag Default Description
--controller-class novaedge.io/proxy loadBalancerClass this controller handles

RedirectSchemeConfig

Configures automatic HTTP to HTTPS redirection on a ProxyGateway.

Field Type Default Description
enabled bool false Enable scheme redirection
scheme string "https" Target scheme
port int32 443 Target port
statusCode int32 301 HTTP redirect status code (301 or 302)
exclusions []string [] Paths to exclude from redirection

AccessLogConfig (Enhanced)

Configures access logging on a ProxyGateway or ProxyRoute.

Field Type Default Description
enabled bool true Enable access logging
format string "json" Log format: json, clf, or custom
template string "" Custom Go template (for format=custom)
output string "stdout" Output destination: stdout, file, or both
filePath string "" Log file path (required for file/both output)
maxSize string "100Mi" Maximum log file size before rotation
maxBackups int32 5 Number of rotated files to keep
filterStatusCodes []int32 [] Status codes to log (empty = all)
sampleRate float64 1.0 Fraction of requests to log (0.0-1.0)

CustomErrorPage

Defines custom error pages on a ProxyGateway.

Field Type Default Description
codes []int32 required HTTP status codes this page applies to
path string "" Path to serve for these error codes
body string "" HTML template body (supports template variables)
contentType string "text/html" Response Content-Type header

Template Variables

Variable Description
{{.StatusCode}} HTTP status code (e.g., 404)
{{.StatusText}} HTTP status text (e.g., "Not Found")
{{.RequestID}} X-Request-ID header value
{{.Timestamp}} UTC timestamp in RFC3339 format

ClientAuthConfig

Client certificate authentication settings for a listener.

Field Type Required Default Description
mode string No none Client auth mode: none, optional, require
caCertRef SecretReference No - Secret containing CA cert for client verification (must have ca.crt key)
requiredCNPatterns []string No - Regex patterns the client cert CN must match
requiredSANs []string No - SANs the client cert must contain

ProxyProtocolConfig

PROXY protocol configuration for a listener.

Field Type Required Default Description
enabled bool No false Enable PROXY protocol parsing
version int32 No 0 Version: 0 (both), 1 (v1 only), 2 (v2 only)
trustedCIDRs []string No [] (all) Source CIDRs from which PROXY headers are accepted

UpstreamProxyProtocolConfig

PROXY protocol configuration for backend connections.

Field Type Required Default Description
enabled bool No false Enable sending PROXY protocol headers to backends
version int32 No 1 Version: 1 or 2

ProxyCertificate DNS-01 and TLS-ALPN-01 Fields

DNS01Config

Added to ACMEIssuerConfig:

Field Type Required Description
provider string Yes DNS provider: cloudflare, route53, googledns
credentialsRef LocalObjectReference Yes Reference to Secret with DNS provider credentials
propagationTimeout string No Max wait for DNS propagation (default: 120s)
pollingInterval string No DNS check interval (default: 5s)

TLSALPN01Config

Added to ACMEIssuerConfig:

Field Type Required Description
port int32 No Port to listen on (default: 443)

VaultPKIIssuerConfig

Added to CertificateIssuer:

Field Type Required Description
path string Yes Vault PKI mount path (e.g., pki-int)
role string Yes Vault PKI role name
ttl string No Requested certificate TTL

ProxyGateway New Fields

VaultCertReference

Added to TLSConfig:

Field Type Required Description
path string Yes Vault PKI mount path
role string Yes Vault PKI role name
ttl string No Requested certificate TTL
cacheSecretName string No K8s Secret to cache the cert

Cert-Manager Annotations

Annotation Description
cert-manager.io/cluster-issuer Create Certificate CR using this ClusterIssuer
cert-manager.io/issuer Create Certificate CR using this namespaced Issuer

ProxyPolicy New Fields

VaultSecretReference

Added to JWTConfig:

Field Type Required Description
path string Yes Vault secret path
key string Yes Key within the secret
engine string No Vault engine type: kv-v1, kv-v2 (default: kv-v2)
refreshInterval string No Secret refresh interval (default: 5m)

Gateway API Resources

NovaEdge supports standard Kubernetes Gateway API resources in addition to its custom CRDs.

GatewayClass

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: novaedge
spec:
  controllerName: novaedge.io/gateway-controller
  description: "NovaEdge Gateway Controller"

Status Conditions:

Condition Description
Accepted True when the controller recognizes the GatewayClass
SupportedVersion True when the Gateway API version is supported

Gateway

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: example-gateway
  namespace: default
spec:
  gatewayClassName: novaedge
  listeners:
  - name: http
    protocol: HTTP
    port: 80
  - name: https
    protocol: HTTPS
    port: 443
    tls:
      mode: Terminate
      certificateRefs:
      - kind: Secret
        name: tls-secret

Status Conditions:

Condition Description
Accepted Gateway accepted by the controller
Programmed Gateway ready to accept traffic

Listener Status Conditions:

Condition Description
Accepted Listener configuration is valid
Programmed Listener is ready
ResolvedRefs All TLS references resolved
Conflicted Listener has port/hostname conflicts

HTTPRoute

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-route
  namespace: default
spec:
  parentRefs:
  - name: example-gateway
  hostnames:
  - "example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api
    backendRefs:
    - name: api-service
      port: 8080

Parent Status Conditions:

Condition Description
Accepted Route accepted by the parent Gateway
ResolvedRefs All backend references resolved

For detailed Gateway API documentation, see Gateway API Guide.