Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
68acb6c
feat: Add cell-local NLB backend health contract
scotwells Oct 12, 2026
e060b0d
fix: Satisfy health probe lint checks
scotwells Oct 12, 2026
47fdeef
chore: Sync health with local NLB addresses
scotwells Oct 12, 2026
c6ca6d4
feat(nlb): align backend health with unweighted route API
scotwells Oct 21, 2026
ec803d0
Merge revised route reconciliation
scotwells Oct 21, 2026
b387aaf
Merge route registration test
scotwells Oct 21, 2026
a988da3
feat(nlb): register cell health runner in unavailable state
scotwells Oct 21, 2026
f283d9e
style(nlb): format backend health API
scotwells Oct 21, 2026
0f936be
Merge backend claim gate
scotwells Oct 21, 2026
14b67aa
Merge backend claim lint fix
scotwells Oct 21, 2026
9875e4d
Merge branch 'codex/nlb-api-foundation' into codex/nlb-health
scotwells Oct 21, 2026
853e1bf
Fail closed on backend health attachment UID mismatch
scotwells Oct 22, 2026
d738ca8
Merge remote-tracking branch 'refs/remotes/github/codex/nlb-route-rec…
scotwells Oct 22, 2026
3ef1af9
fix: start NLB probe timeout after capacity wait
scotwells Oct 22, 2026
f108b60
Merge remote-tracking branch 'github/codex/nlb-route-reconcile' into …
scotwells Oct 22, 2026
3f77671
Merge remote-tracking branch 'github/codex/nlb-route-reconcile' into …
scotwells Oct 22, 2026
1e9d69d
Keep full NLB health sweeps fresh and count successive probes
scotwells Oct 22, 2026
1e14d03
Merge remote-tracking branch 'github/codex/nlb-route-reconcile' into …
scotwells Oct 22, 2026
842f7a0
Cover NLB health freshness across reordered probe sweeps
scotwells Oct 22, 2026
06d540f
Merge branch 'codex/nlb-route-reconcile' into codex/nlb-health
scotwells Oct 22, 2026
af230e6
Bound health freshness across full probe sweeps
scotwells Oct 22, 2026
6e423e5
Align health expiry regression with computed window
scotwells Oct 22, 2026
45c595f
Merge branch 'codex/nlb-route-reconcile' into codex/nlb-health
scotwells Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/v1alpha/groupversion_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&NetworkInterfaceList{},
&NetworkInterfaceClaim{},
&NetworkInterfaceClaimList{},
&NetworkLoadBalancerBackendHealth{},
&NetworkLoadBalancerBackendHealthList{},
&NetworkLoadBalancer{},
&NetworkLoadBalancerList{},
&NetworkLoadBalancerRoute{},
Expand Down
6 changes: 6 additions & 0 deletions api/v1alpha/networkinterface_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package v1alpha

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

// NetworkInterfaceReclaimPolicy decides what becomes of an interface, and the
Expand Down Expand Up @@ -258,6 +259,11 @@ type NetworkInterfaceAttachmentRef struct {
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
Name string `json:"name"`

// uid identifies the exact attachment incarnation. Probe consumers require
// this value so a recreated attachment cannot inherit the prior health.
// +kubebuilder:validation:Optional
UID types.UID `json:"uid,omitempty"`
}

// NetworkInterfaceSpec defines the desired state of NetworkInterface. It is
Expand Down
143 changes: 143 additions & 0 deletions api/v1alpha/networkloadbalancerbackendhealth_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// SPDX-License-Identifier: AGPL-3.0-only

package v1alpha

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

// +kubebuilder:validation:Enum=TCP;HTTP;HTTPS
type NetworkLoadBalancerProbeProtocol string

const (
NetworkLoadBalancerProbeTCP NetworkLoadBalancerProbeProtocol = "TCP"
NetworkLoadBalancerProbeHTTP NetworkLoadBalancerProbeProtocol = "HTTP"
NetworkLoadBalancerProbeHTTPS NetworkLoadBalancerProbeProtocol = "HTTPS"
)

type NetworkLoadBalancerBackendHealthRouteRef struct {
// +kubebuilder:validation:MinLength=1
Namespace string `json:"namespace"`
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`
UID types.UID `json:"uid"`
// +kubebuilder:validation:Minimum=1
Generation int64 `json:"generation"`
}

type NetworkLoadBalancerBackendHealthParentRef struct {
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`
UID types.UID `json:"uid"`
// +kubebuilder:validation:Minimum=1
Generation int64 `json:"generation"`
// +kubebuilder:validation:MinLength=1
Listener string `json:"listener"`
}

// NetworkLoadBalancerProbe describes a resolved active check. Its port is a
// backend port number, not a listener port or a NetworkService port name.
// +kubebuilder:validation:XValidation:message="path is only valid for HTTP and HTTPS",rule="has(self.path) ? self.protocol in ['HTTP', 'HTTPS'] : true"
// +kubebuilder:validation:XValidation:message="serverName is only valid for HTTPS",rule="has(self.serverName) ? self.protocol == 'HTTPS' : true"
type NetworkLoadBalancerProbe struct {
Protocol NetworkLoadBalancerProbeProtocol `json:"protocol"`
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
Port int32 `json:"port"`
// +kubebuilder:validation:Optional
// +kubebuilder:validation:Pattern=`^/.*$`
// +kubebuilder:validation:MaxLength=256
Path string `json:"path,omitempty"`
// +kubebuilder:validation:Optional
// +kubebuilder:validation:MaxLength=253
ServerName string `json:"serverName,omitempty"`
}

// NetworkLoadBalancerBackendHealthTarget identifies one resolved interface
// endpoint and its probe. The source UID prevents a replacement interface
// reusing a name from inheriting a previous endpoint's health.
type NetworkLoadBalancerBackendHealthTarget struct {
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=63
Name string `json:"name"`
// +kubebuilder:validation:MinLength=1
SourceNamespace string `json:"sourceNamespace"`
// +kubebuilder:validation:MinLength=1
SourceInterface string `json:"sourceInterface"`
SourceUID types.UID `json:"sourceUID"`
// +kubebuilder:validation:MinLength=1
AttachmentName string `json:"attachmentName"`
AttachmentUID types.UID `json:"attachmentUID"`
// +kubebuilder:validation:MinLength=1
Address string `json:"address"`
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
ServingPort int32 `json:"servingPort"`
Probe NetworkLoadBalancerProbe `json:"probe"`
}

// NetworkLoadBalancerBackendHealthSpec carries one route parent and location's
// resolved targets into the cell that can reach them.
type NetworkLoadBalancerBackendHealthSpec struct {
RouteRef NetworkLoadBalancerBackendHealthRouteRef `json:"routeRef"`
ParentRef NetworkLoadBalancerBackendHealthParentRef `json:"parentRef"`
// +kubebuilder:validation:MinLength=1
Location string `json:"location"`
// +kubebuilder:validation:MinLength=1
NetworkName string `json:"networkName"`
// +kubebuilder:validation:MinLength=1
FabricVPCID string `json:"fabricVPCID"`
// +kubebuilder:validation:MaxItems=64
// +listType=map
// +listMapKey=name
Targets []NetworkLoadBalancerBackendHealthTarget `json:"targets"`
}

// NetworkLoadBalancerBackendHealthTargetStatus is usable only while its route,
// object generation, target fingerprint, and expiry match current intent.
type NetworkLoadBalancerBackendHealthTargetStatus struct {
Name string `json:"name"`
ObservedGeneration int64 `json:"observedGeneration"`
RouteUID types.UID `json:"routeUID"`
RouteGeneration int64 `json:"routeGeneration"`
TargetFingerprint string `json:"targetFingerprint"`
Healthy bool `json:"healthy"`
ConsecutiveSuccesses int32 `json:"consecutiveSuccesses"`
LastProbeTime metav1.Time `json:"lastProbeTime"`
ValidUntil metav1.Time `json:"validUntil"`
Reason string `json:"reason,omitempty"`
}

type NetworkLoadBalancerBackendHealthStatus struct {
// ProbesEvaluated remains Unknown until a VPC-capable runner reports results.
// +listType=map
// +listMapKey=type
Conditions []metav1.Condition `json:"conditions,omitempty"`

// +kubebuilder:validation:MaxItems=64
// +listType=map
// +listMapKey=name
Targets []NetworkLoadBalancerBackendHealthTargetStatus `json:"targets,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status

// NetworkLoadBalancerBackendHealth is an internal, cell-local probe contract.
// A target is eligible for data plane programming only after a fresh success.
type NetworkLoadBalancerBackendHealth struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec NetworkLoadBalancerBackendHealthSpec `json:"spec"`
// +kubebuilder:default={conditions:{{type:"ProbesEvaluated",status:"Unknown",reason:"Pending",message:"Waiting for a VPC-capable probe runner",lastTransitionTime:"1970-01-01T00:00:00Z"}}}
Status NetworkLoadBalancerBackendHealthStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

type NetworkLoadBalancerBackendHealthList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []NetworkLoadBalancerBackendHealth `json:"items"`
}
188 changes: 188 additions & 0 deletions api/v1alpha/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,11 @@ spec:
maxLength: 253
minLength: 1
type: string
uid:
description: |-
uid identifies the exact attachment incarnation. Probe consumers require
this value so a recreated attachment cannot inherit the prior health.
type: string
required:
- apiGroup
- kind
Expand Down
Loading
Loading