Skip to content
Closed
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
119 changes: 119 additions & 0 deletions api/v1alpha1/sandbox_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package v1alpha1
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
intstr "k8s.io/apimachinery/pkg/util/intstr"
)

// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
Expand All @@ -30,10 +31,128 @@ type SandboxSpec struct {
// PodTemplate describes the pod spec that will be used to create an agent sandbox.
// +kubebuilder:validation:Required
PodTemplate corev1.PodTemplateSpec `json:"podTemplate" protobuf:"bytes,3,opt,name=podTemplate"`

// Networking describes optional external exposure and/or references to
// externally managed routes for this sandbox. If omitted, only the default
// headless Service (for internal discovery) is used.
// +optional
Networking *NetworkingSpec `json:"networking,omitempty"`

// Pause, when true, indicates the sandbox should be stopped.
// The controller ensures no Pod is running, while preserving the Sandbox
// object and persistent state. When false, the controller ensures the Pod
// is running as specified by PodTemplate.
// +optional
Pause *bool `json:"pause,omitempty"`

// Schedule provides time-based lifecycle controls for the sandbox.
// +optional
Schedule *Schedule `json:"schedule,omitempty"`
}

// SandboxStatus defines the observed state of Sandbox.
type SandboxStatus struct {
// Conditions represent the latest available observations of the sandbox's state.
// Common conditions may include Ready, Stopped, Resuming, Scheduled, NetworkingReady.
// +optional
Conditions []Condition `json:"conditions,omitempty"`

// Networking exposes observed reachability information, such as URLs, IPs
// and ports, derived from Services/Routes referenced by spec.networking.
// +optional
Networking []NetworkingStatus `json:"networking,omitempty"`
}

// Schedule defines time-based lifecycle behavior for a sandbox.
type Schedule struct {
// ShutdownTime is the time to stop the sandbox, in RFC3339 format
// (e.g. 2025-07-01T00:00:00Z). When reached, the controller should ensure
// the sandbox is paused.
// +kubebuilder:validation:Format=date-time
// +optional
ShutdownTime string `json:"shutdownTime,omitempty"`
}

// Condition is a wrapper around metav1.Condition for CRD compatibility and
// future extension.
type Condition struct {
metav1.Condition `json:",inline"`
}

// NetworkingSpec describes optional exposure configuration and external route refs.
type NetworkingSpec struct {
// Service describes an optional Service to create for exposure.
// If omitted, only the internal headless Service is maintained for discovery.
// +optional
Service *ServiceSpec `json:"service,omitempty"`

// RouteRefs references externally managed routing resources (e.g., Gateway API
// HTTPRoute/TCPRoute or Ingress) that target the sandbox Service.
// The controller may read these for observability but does not create them.
// +optional
RouteRefs []RouteRef `json:"routeRefs,omitempty"`
}

// ServiceSpec is a minimal, opinion-neutral subset to describe a Service exposure.
type ServiceSpec struct {
// Type determines exposure level. ClusterIP for in-cluster, NodePort/LoadBalancer for external.
// +kubebuilder:validation:Enum=ClusterIP;NodePort;LoadBalancer
// +optional
Type corev1.ServiceType `json:"type,omitempty"`

// Ports to expose on the Service.
// +optional
Ports []ServicePort `json:"ports,omitempty"`
}

// ServicePort describes a single Service port mapping.
type ServicePort struct {
// Name should align with the container port name when TargetPort is omitted.
// +optional
Name string `json:"name,omitempty"`

// Port is the Service port.
Port int32 `json:"port"`

// TargetPort is the target Pod port. If omitted and Name is set, the controller
// may resolve the container port by name.
// +optional
TargetPort intstr.IntOrString `json:"targetPort,omitempty"`

// Protocol defaults to TCP.
// +kubebuilder:validation:Enum=TCP;UDP;SCTP
// +optional
Protocol corev1.Protocol `json:"protocol,omitempty"`
}

// RouteRef references an external routing resource in the same namespace.
type RouteRef struct {
// Kind of the route resource (e.g., HTTPRoute, TCPRoute, Ingress).
Kind string `json:"kind"`
// Name of the referenced route resource.
Name string `json:"name"`
}

// NetworkingStatus captures observed reachability information.
type NetworkingStatus struct {
// Name associates with a port/name when applicable.
// +optional
Name string `json:"name,omitempty"`
// URL is an externally reachable URL if known (e.g., from a Route/Ingress).
// +optional
URL string `json:"url,omitempty"`
// IP is an external IP if assigned (e.g., LoadBalancer ingress).
// +optional
IP string `json:"ip,omitempty"`
// Port is the externally reachable port.
// +optional
Port int32 `json:"port,omitempty"`
// Ready indicates whether networking is considered ready.
// +optional
Ready bool `json:"ready,omitempty"`
// Message provides human-readable details.
// +optional
Message string `json:"message,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
151 changes: 150 additions & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

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

Loading