Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions api/v1alpha/groupversion_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&NetworkInterfaceList{},
&NetworkInterfaceClaim{},
&NetworkInterfaceClaimList{},
&NetworkLoadBalancerBackendHealth{},
&NetworkLoadBalancerBackendHealthList{},
&NetworkLoadBalancer{},
&NetworkLoadBalancerList{},
&NetworkLoadBalancerCellIntent{},
&NetworkLoadBalancerCellIntentList{},
&NetworkLoadBalancerRoute{},
&NetworkLoadBalancerRouteList{},
&NetworkPolicy{},
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 @@ -262,6 +263,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"`
}
94 changes: 94 additions & 0 deletions api/v1alpha/networkloadbalancercellintent_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: AGPL-3.0-only

package v1alpha

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

// NetworkLoadBalancerCellIntentState distinguishes desired backend validation
// from an explicit withdrawal. Neither state authorizes traffic programming.
// +kubebuilder:validation:Enum=Validate;Withdrawn
type NetworkLoadBalancerCellIntentState string

const (
NetworkLoadBalancerCellIntentValidate NetworkLoadBalancerCellIntentState = "Validate"
NetworkLoadBalancerCellIntentWithdrawn NetworkLoadBalancerCellIntentState = "Withdrawn"
)

type NetworkLoadBalancerCellIntentSource struct {
// +kubebuilder:validation:MinLength=1
ProjectCluster string `json:"projectCluster"`
// +kubebuilder:validation:MinLength=1
Namespace string `json:"namespace"`
// +kubebuilder:validation:MinLength=1
RouteName string `json:"routeName"`
// +kubebuilder:validation:MinLength=1
RouteUID string `json:"routeUID"`
RouteGeneration int64 `json:"routeGeneration"`
// +kubebuilder:validation:MinLength=1
ParentName string `json:"parentName"`
// +kubebuilder:validation:MinLength=1
ParentUID string `json:"parentUID"`
ParentGeneration int64 `json:"parentGeneration"`
// +kubebuilder:validation:MinLength=1
ListenerName string `json:"listenerName"`
// +kubebuilder:validation:MinLength=1
AddressRequest string `json:"addressRequest"`
}

type NetworkLoadBalancerCellIntentProbe struct {
Protocol string `json:"protocol"`
Port int32 `json:"port"`
Path string `json:"path,omitempty"`
}

type NetworkLoadBalancerCellIntentBackend struct {
// +kubebuilder:validation:MinLength=1
SourceNamespace string `json:"sourceNamespace"`
// +kubebuilder:validation:MinLength=1
SourceName string `json:"sourceName"`
// +kubebuilder:validation:MinLength=1
SourceUID string `json:"sourceUID"`
// Family identifies the backend transport address independently of the
// public VIP family. IPv4 ingress can use an IPv6 backend through a proxy.
Family IPFamily `json:"family"`
// +kubebuilder:validation:MinLength=1
Address string `json:"address"`
Port int32 `json:"port"`
Probe NetworkLoadBalancerCellIntentProbe `json:"probe"`
}

// NetworkLoadBalancerCellIntentSpec is a validation request to one location.
// The cell must independently verify the live interface, attachment, and VPC.
// +kubebuilder:validation:XValidation:message="Validate needs backends; Withdrawn must have none",rule="self.state == 'Validate' ? has(self.backends) && size(self.backends) > 0 : !has(self.backends) || size(self.backends) == 0"
type NetworkLoadBalancerCellIntentSpec struct {
Source NetworkLoadBalancerCellIntentSource `json:"source"`
Location string `json:"location"`
NetworkName string `json:"networkName"`
// VIPFamily selects the ingress packet path. It may differ from a backend's
// family; the serving cell must support that family pair before programming.
VIPFamily IPFamily `json:"vipFamily"`
VIP string `json:"vip"`
Protocol NetworkLoadBalancerProtocol `json:"protocol"`
ListenerPort int32 `json:"listenerPort"`
State NetworkLoadBalancerCellIntentState `json:"state"`
// +kubebuilder:validation:MaxItems=1024
Backends []NetworkLoadBalancerCellIntentBackend `json:"backends,omitempty"`
}

// +kubebuilder:object:root=true
// NetworkLoadBalancerCellIntent carries a scoped, non-serving desired state
// from a project control plane through the hub to the serving cell.
type NetworkLoadBalancerCellIntent struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec NetworkLoadBalancerCellIntentSpec `json:"spec"`
}

// +kubebuilder:object:root=true

type NetworkLoadBalancerCellIntentList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []NetworkLoadBalancerCellIntent `json:"items"`
}
Loading
Loading