diff --git a/.golangci-kal.yml b/.golangci-kal.yml
index a5d853bfe..099d81da6 100644
--- a/.golangci-kal.yml
+++ b/.golangci-kal.yml
@@ -32,6 +32,8 @@ linters:
policy: SuggestFix # SuggestFix | Warn # The policy for pointers in optional fields. Defaults to `SuggestFix`.
omitempty:
policy: SuggestFix # SuggestFix | Warn | Ignore # The policy for omitempty in optional fields. Defaults to `SuggestFix`.
+ omitzero:
+ policy: Forbid # Enforce the `omitempty` route with a pointer for all optional structs.
exclusions:
generated: strict
paths:
diff --git a/api/v1/inferencepool_types.go b/api/v1/inferencepool_types.go
index 12f47deed..05c7c9f88 100644
--- a/api/v1/inferencepool_types.go
+++ b/api/v1/inferencepool_types.go
@@ -35,17 +35,18 @@ type InferencePool struct {
// +optional
metav1.ObjectMeta `json:"metadata,omitempty"`
+ // Spec defines the desired state of the InferencePool.
+ //
// +required
Spec InferencePoolSpec `json:"spec,omitzero"`
- // Status defines the observed state of InferencePool.
+ // Status defines the observed state of the InferencePool.
//
- // +kubebuilder:default={parent: {{parentRef: {kind: "Status", name: "default"}, conditions: {{type: "Accepted", status: "Unknown", reason: "Pending", message: "Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}}}}
// +optional
- Status InferencePoolStatus `json:"status,omitzero"`
+ Status InferencePoolStatus `json:"status,omitempty"`
}
-// InferencePoolList contains a list of InferencePool.
+// InferencePoolList contains a list of InferencePools.
//
// +kubebuilder:object:root=true
type InferencePoolList struct {
@@ -54,7 +55,7 @@ type InferencePoolList struct {
Items []InferencePool `json:"items"`
}
-// InferencePoolSpec defines the desired state of InferencePool
+// InferencePoolSpec defines the desired state of the InferencePool.
type InferencePoolSpec struct {
// Selector determines which Pods are members of this inference pool.
// It matches Pods by their labels only within the same namespace; cross-namespace
@@ -65,19 +66,22 @@ type InferencePoolSpec struct {
// this configuration into a Service resource.
//
// +required
- Selector LabelSelector `json:"selector,omitempty,omitzero"`
+ Selector LabelSelector `json:"selector,omitzero"`
// TargetPorts defines a list of ports that are exposed by this InferencePool.
// Currently, the list may only include a single port definition.
+ //
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=1
// +listType=atomic
// +required
- TargetPorts []Port `json:"targetPorts,omitempty"`
+ TargetPorts []Port `json:"targetPorts,omitzero"`
- // EndpointPickerRef configures an endpoint picker as an extension service.
+ // EndpointPickerRef is a reference to the Endpoint Picker extension and its
+ // associated configuration.
+ //
// +required
- EndpointPickerRef EndpointPickerRef `json:"endpointPickerRef,omitempty,omitzero"`
+ EndpointPickerRef EndpointPickerRef `json:"endpointPickerRef,omitzero"`
}
// Port defines the network port that will be exposed by this InferencePool.
@@ -86,13 +90,14 @@ type Port struct {
// The number must be in the range 1 to 65535.
//
// +required
- Number PortNumber `json:"number,omitempty"`
+ Number PortNumber `json:"number,omitzero"`
}
-// Extension specifies how to configure an extension that runs the endpoint picker.
+// EndpointPickerRef specifies a reference to an Endpoint Picker extension and its
+// associated configuration.
type EndpointPickerRef struct {
- // Group is the group of the referent.
- // The default value is "", representing the Core API group.
+ // Group is the group of the referent API object. When unspecified, the default value
+ // is "", representing the Core API group.
//
// +optional
// +kubebuilder:default=""
@@ -100,7 +105,7 @@ type EndpointPickerRef struct {
// Kind is the Kubernetes resource kind of the referent.
//
- // Required if the referent is ambiguous(e.g. service with one port is unambiguous).
+ // Required if the referent is ambiguous, e.g. service with multiple ports.
//
// Defaults to "Service" when not specified.
//
@@ -112,67 +117,68 @@ type EndpointPickerRef struct {
//
// +optional
// +kubebuilder:default=Service
- Kind Kind `json:"kind,omitempty"`
+ Kind *Kind `json:"kind,omitempty"`
- // Name is the name of the referent.
+ // Name is the name of the referent API object.
//
// +required
- Name ObjectName `json:"name,omitempty"`
+ Name ObjectName `json:"name,omitzero"`
- // The port number on the service running the extension. When unspecified,
- // implementations SHOULD infer a default value of 9002 when the Kind is
- // Service.
+ // PortNumber is the port number of the Endpoint Picker extension service. When unspecified,
+ // implementations SHOULD infer a default value of 9002 when the kind field is "Service" or
+ // unspecified (defaults to "Service").
//
// +optional
- //nolint:kubeapilinter // ignore kubeapilinter here as we want to use pointer here as 0 usually means all ports.
PortNumber *PortNumber `json:"portNumber,omitempty"`
- // Configures how the gateway handles the case when the extension is not responsive.
- // Defaults to failClose.
+ // FailureMode configures how the parent handles the case when the Endpoint Picker extension
+ // is non-responsive. When unspecified, defaults to "FailClose".
//
// +optional
// +kubebuilder:default="FailClose"
- FailureMode ExtensionFailureMode `json:"failureMode,omitempty"`
+ FailureMode *EndpointPickerFailureMode `json:"failureMode,omitempty"`
}
-// ExtensionFailureMode defines the options for how the gateway handles the case when the extension is not
-// responsive.
+// EndpointPickerFailureMode defines the options for how the parent handles the case when the
+// Endpoint Picker extension is non-responsive.
+//
// +kubebuilder:validation:Enum=FailOpen;FailClose
-type ExtensionFailureMode string
+type EndpointPickerFailureMode string
const (
- // FailOpen specifies that the proxy should forward the request to an endpoint of its picking when the Endpoint Picker fails.
- FailOpen ExtensionFailureMode = "FailOpen"
- // FailClose specifies that the proxy should drop the request when the Endpoint Picker fails.
- FailClose ExtensionFailureMode = "FailClose"
+ // EndpointPickerFailOpen specifies that the parent should forward the request to an endpoint
+ // of its picking when the Endpoint Picker extension fails.
+ EndpointPickerFailOpen EndpointPickerFailureMode = "FailOpen"
+ // EndpointPickerFailClose specifies that the parent should drop the request when the Endpoint
+ // Picker extension fails.
+ EndpointPickerFailClose EndpointPickerFailureMode = "FailClose"
)
-// InferencePoolStatus defines the observed state of InferencePool.
-// +kubebuilder:validation:MinProperties=1
+// InferencePoolStatus defines the observed state of the InferencePool.
type InferencePoolStatus struct {
- // Parents is a list of parent resources (usually Gateways) that are
- // associated with the InferencePool, and the status of the InferencePool with respect to
- // each parent.
+ // Parents is a list of parent resources, typically Gateways, that are associated with
+ // the InferencePool, and the status of the InferencePool with respect to each parent.
//
- // A maximum of 32 Gateways will be represented in this list. When the list contains
- // `kind: Status, name: default`, it indicates that the InferencePool is not
- // associated with any Gateway and a controller must perform the following:
+ // A controller that manages the InferencePool, must add an entry for each parent it manages
+ // and remove the parent entry when the controller no longer considers the InferencePool to
+ // be associated with that parent.
//
- // - Remove the parent when setting the "Accepted" condition.
- // - Add the parent when the controller will no longer manage the InferencePool
- // and no other parents exist.
+ // A maximum of 32 parents will be represented in this list. When the list is empty,
+ // it indicates that the InferencePool is not associated with any parents.
//
// +kubebuilder:validation:MaxItems=32
// +optional
// +listType=atomic
- Parents []PoolStatus `json:"parent,omitempty"`
+ Parents []ParentStatus `json:"parents,omitempty"`
}
-// PoolStatus defines the observed state of InferencePool from a Gateway.
-type PoolStatus struct {
- // Conditions track the state of the InferencePool.
+// ParentStatus defines the observed state of InferencePool from a Parent, i.e. Gateway.
+type ParentStatus struct {
+ // Conditions is a list of status conditions that provide information about the observed
+ // state of the InferencePool. This field is required to be set by the controller that
+ // manages the InferencePool.
//
- // Known condition types are:
+ // Supported condition types are:
//
// * "Accepted"
// * "ResolvedRefs"
@@ -180,32 +186,36 @@ type PoolStatus struct {
// +optional
// +listType=map
// +listMapKey=type
+ // +patchStrategy=merge
+ // +patchMergeKey=type
// +kubebuilder:validation:MaxItems=8
- // +kubebuilder:default={{type: "Accepted", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}
Conditions []metav1.Condition `json:"conditions,omitempty"`
- // GatewayRef indicates the gateway that observed state of InferencePool.
+ // ParentRef is used to identify the parent resource that this status
+ // is associated with. It is used to match the InferencePool with the parent
+ // resource, such as a Gateway.
+ //
// +required
- GatewayRef ParentGatewayReference `json:"parentRef,omitzero"`
+ ParentRef ParentReference `json:"parentRef,omitzero"`
}
-// InferencePoolConditionType is a type of condition for the InferencePool
+// InferencePoolConditionType is a type of status condition for the InferencePool.
type InferencePoolConditionType string
-// InferencePoolReason is the reason for a given InferencePoolConditionType
+// InferencePoolReason is the reason for a type of InferencePool status condition.
type InferencePoolReason string
const (
- // This condition indicates whether the InferencePool has been accepted or rejected
- // by a Gateway, and why.
+ // InferencePoolConditionAccepted is a type of condition that indicates whether
+ // the InferencePool has been accepted or rejected by a Parent, and why.
//
// Possible reasons for this condition to be True are:
//
- // * "Accepted"
+ // * "SupportedByParent"
//
// Possible reasons for this condition to be False are:
//
- // * "NotSupportedByGateway"
+ // * "Accepted"
// * "HTTPRouteNotAccepted"
//
// Possible reasons for this condition to be Unknown are:
@@ -216,28 +226,26 @@ const (
// prefer to use the reasons listed above to improve interoperability.
InferencePoolConditionAccepted InferencePoolConditionType = "Accepted"
- // This reason is used with the "Accepted" condition when the InferencePool has been
- // accepted by the Gateway.
+ // InferencePoolReasonAccepted is a reason used with the "Accepted" condition
+ // when the InferencePool is accepted by a Parent because the Parent supports
+ // InferencePool as a backend.
InferencePoolReasonAccepted InferencePoolReason = "Accepted"
- // This reason is used with the "Accepted" condition when the InferencePool
- // has not been accepted by a Gateway because the Gateway does not support
- // InferencePool as a backend.
- InferencePoolReasonNotSupportedByGateway InferencePoolReason = "NotSupportedByGateway"
+ // InferencePoolReasonNotSupportedByParent is a reason used with the "Accepted"
+ // condition when the InferencePool has not been accepted by a Parent because
+ // the Parent does not support InferencePool as a backend.
+ InferencePoolReasonNotSupportedByParent InferencePoolReason = "NotSupportedByParent"
- // This reason is used with the "Accepted" condition when the InferencePool is
- // referenced by an HTTPRoute that has been rejected by the Gateway. The user
- // should inspect the status of the referring HTTPRoute for the specific reason.
+ // InferencePoolReasonHTTPRouteNotAccepted is an optional reason used with the
+ // "Accepted" condition when the InferencePool is referenced by an HTTPRoute that
+ // has been rejected by the Parent. The user should inspect the status of the
+ // referring HTTPRoute for the specific reason.
InferencePoolReasonHTTPRouteNotAccepted InferencePoolReason = "HTTPRouteNotAccepted"
-
- // This reason is used with the "Accepted" when a controller has not yet
- // reconciled the InferencePool.
- InferencePoolReasonPending InferencePoolReason = "Pending"
)
const (
- // This condition indicates whether the controller was able to resolve all
- // the object references for the InferencePool.
+ // InferencePoolConditionResolvedRefs is a type of condition that indicates whether
+ // the controller was able to resolve all the object references for the InferencePool.
//
// Possible reasons for this condition to be True are:
//
@@ -251,39 +259,46 @@ const (
// prefer to use the reasons listed above to improve interoperability.
InferencePoolConditionResolvedRefs InferencePoolConditionType = "ResolvedRefs"
- // This reason is used with the "ResolvedRefs" condition when the condition
- // is true.
+ // InferencePoolReasonResolvedRefs is a reason used with the "ResolvedRefs"
+ // condition when the condition is true.
InferencePoolReasonResolvedRefs InferencePoolReason = "ResolvedRefs"
- // This reason is used with the "ResolvedRefs" condition when the
- // Extension is invalid in some way. This can include an unsupported kind
- // or API group, or a reference to a resource that can not be found.
+ // InferencePoolReasonInvalidExtensionRef is a reason used with the "ResolvedRefs"
+ // condition when the Extension is invalid in some way. This can include an
+ // unsupported kind or API group, or a reference to a resource that cannot be found.
InferencePoolReasonInvalidExtensionRef InferencePoolReason = "InvalidExtensionRef"
)
-// ParentGatewayReference identifies an API object including its namespace,
-// defaulting to Gateway.
-type ParentGatewayReference struct {
- // Group is the group of the referent.
+// ParentReference identifies an API object. It is used to associate the InferencePool with a
+// parent resource, such as a Gateway.
+type ParentReference struct {
+ // Group is the group of the referent API object. When unspecified, the referent is assumed
+ // to be in the "gateway.networking.k8s.io" API group.
//
// +optional
// +kubebuilder:default="gateway.networking.k8s.io"
Group *Group `json:"group,omitempty"`
- // Kind is kind of the referent. For example "Gateway".
+ // Kind is the kind of the referent API object. When unspecified, the referent is assumed
+ // to be a "Gateway" kind.
//
// +optional
// +kubebuilder:default=Gateway
- Kind Kind `json:"kind,omitempty"`
+ Kind *Kind `json:"kind,omitempty"`
- // Name is the name of the referent.
+ // Name is the name of the referent API object.
+ //
// +required
- Name ObjectName `json:"name,omitempty"`
+ Name ObjectName `json:"name,omitzero"`
- // Namespace is the namespace of the referent. If not present,
- // the namespace of the referent is assumed to be the same as
- // the namespace of the referring object.
+ // Namespace is the namespace of the referenced object. When unspecified, the local
+ // namespace is inferred.
+ //
+ // Note that when a namespace different than the local namespace is specified,
+ // a ReferenceGrant object is required in the referent namespace to allow that
+ // namespace's owner to accept the reference. See the ReferenceGrant
+ // documentation for details: https://gateway-api.sigs.k8s.io/api-types/referencegrant/
//
// +optional
- Namespace Namespace `json:"namespace,omitempty"`
+ Namespace *Namespace `json:"namespace,omitempty"`
}
diff --git a/api/v1/shared_types.go b/api/v1/shared_types.go
index 64425e735..992838c71 100644
--- a/api/v1/shared_types.go
+++ b/api/v1/shared_types.go
@@ -132,11 +132,12 @@ type LabelValue string
// LabelSelector defines a query for resources based on their labels.
// This simplified version uses only the matchLabels field.
type LabelSelector struct {
- // matchLabels contains a set of required {key,value} pairs.
+ // MatchLabels contains a set of required {key,value} pairs.
// An object must match every label in this map to be selected.
// The matching logic is an AND operation on all entries.
//
// +required
+ // +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=64
- MatchLabels map[LabelKey]LabelValue `json:"matchLabels,omitempty" protobuf:"bytes,1,rep,name=matchLabels"`
+ MatchLabels map[LabelKey]LabelValue `json:"matchLabels,omitzero"`
}
diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go
index 9e90d369f..791bc96e4 100644
--- a/api/v1/zz_generated.deepcopy.go
+++ b/api/v1/zz_generated.deepcopy.go
@@ -33,11 +33,21 @@ func (in *EndpointPickerRef) DeepCopyInto(out *EndpointPickerRef) {
*out = new(Group)
**out = **in
}
+ if in.Kind != nil {
+ in, out := &in.Kind, &out.Kind
+ *out = new(Kind)
+ **out = **in
+ }
if in.PortNumber != nil {
in, out := &in.PortNumber, &out.PortNumber
*out = new(PortNumber)
**out = **in
}
+ if in.FailureMode != nil {
+ in, out := &in.FailureMode, &out.FailureMode
+ *out = new(EndpointPickerFailureMode)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointPickerRef.
@@ -136,7 +146,7 @@ func (in *InferencePoolStatus) DeepCopyInto(out *InferencePoolStatus) {
*out = *in
if in.Parents != nil {
in, out := &in.Parents, &out.Parents
- *out = make([]PoolStatus, len(*in))
+ *out = make([]ParentStatus, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -176,27 +186,37 @@ func (in *LabelSelector) DeepCopy() *LabelSelector {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ParentGatewayReference) DeepCopyInto(out *ParentGatewayReference) {
+func (in *ParentReference) DeepCopyInto(out *ParentReference) {
*out = *in
if in.Group != nil {
in, out := &in.Group, &out.Group
*out = new(Group)
**out = **in
}
+ if in.Kind != nil {
+ in, out := &in.Kind, &out.Kind
+ *out = new(Kind)
+ **out = **in
+ }
+ if in.Namespace != nil {
+ in, out := &in.Namespace, &out.Namespace
+ *out = new(Namespace)
+ **out = **in
+ }
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentGatewayReference.
-func (in *ParentGatewayReference) DeepCopy() *ParentGatewayReference {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentReference.
+func (in *ParentReference) DeepCopy() *ParentReference {
if in == nil {
return nil
}
- out := new(ParentGatewayReference)
+ out := new(ParentReference)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *PoolStatus) DeepCopyInto(out *PoolStatus) {
+func (in *ParentStatus) DeepCopyInto(out *ParentStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
@@ -205,15 +225,15 @@ func (in *PoolStatus) DeepCopyInto(out *PoolStatus) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
- in.GatewayRef.DeepCopyInto(&out.GatewayRef)
+ in.ParentRef.DeepCopyInto(&out.ParentRef)
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolStatus.
-func (in *PoolStatus) DeepCopy() *PoolStatus {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentStatus.
+func (in *ParentStatus) DeepCopy() *ParentStatus {
if in == nil {
return nil
}
- out := new(PoolStatus)
+ out := new(ParentStatus)
in.DeepCopyInto(out)
return out
}
diff --git a/apix/v1alpha2/inferencepool_conversion.go b/apix/v1alpha2/inferencepool_conversion.go
index b817c47d5..7ec7302c2 100644
--- a/apix/v1alpha2/inferencepool_conversion.go
+++ b/apix/v1alpha2/inferencepool_conversion.go
@@ -18,10 +18,9 @@ package v1alpha2
import (
"errors"
- "fmt"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- runtime "k8s.io/apimachinery/pkg/runtime"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/utils/ptr"
v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
)
@@ -39,11 +38,17 @@ func (src *InferencePool) ConvertTo(dst *v1.InferencePool) error {
if err != nil {
return err
}
- dst.TypeMeta = src.TypeMeta
+
+ meta := metav1.TypeMeta{
+ Kind: src.Kind,
+ APIVersion: v1.GroupVersion.String(), // Ensure the API version is set correctly.
+ }
+ dst.TypeMeta = meta
dst.ObjectMeta = src.ObjectMeta
dst.Spec.TargetPorts = []v1.Port{{Number: v1.PortNumber(src.Spec.TargetPortNumber)}}
dst.Spec.EndpointPickerRef = endpointPickRef
dst.Status = *v1Status
+
if src.Spec.Selector != nil {
dst.Spec.Selector.MatchLabels = make(map[v1.LabelKey]v1.LabelValue, len(src.Spec.Selector))
for k, v := range src.Spec.Selector {
@@ -66,11 +71,17 @@ func (dst *InferencePool) ConvertFrom(src *v1.InferencePool) error {
if err != nil {
return err
}
- dst.TypeMeta = src.TypeMeta
+
+ meta := metav1.TypeMeta{
+ Kind: src.Kind,
+ APIVersion: GroupVersion.String(), // Ensure the API version is set correctly.
+ }
+ dst.TypeMeta = meta
dst.ObjectMeta = src.ObjectMeta
dst.Spec.TargetPortNumber = int32(src.Spec.TargetPorts[0].Number)
dst.Spec.ExtensionRef = extensionRef
dst.Status = *status
+
if src.Spec.Selector.MatchLabels != nil {
dst.Spec.Selector = make(map[LabelKey]LabelValue, len(src.Spec.Selector.MatchLabels))
for k, v := range src.Spec.Selector.MatchLabels {
@@ -84,22 +95,90 @@ func convertStatusToV1(src *InferencePoolStatus) (*v1.InferencePoolStatus, error
if src == nil {
return nil, errors.New("src cannot be nil")
}
- u, err := toUnstructured(src)
- if err != nil {
- return nil, err
+ out := &v1.InferencePoolStatus{
+ Parents: make([]v1.ParentStatus, 0, len(src.Parents)),
+ }
+ for _, p := range src.Parents {
+ ps := v1.ParentStatus{
+ ParentRef: toV1ParentRef(p.GatewayRef),
+ Conditions: make([]metav1.Condition, 0, len(p.Conditions)),
+ }
+ for _, c := range p.Conditions {
+ cc := c
+ // v1alpha2: "Accepted" -> v1: "SupportedByParent"
+ if cc.Type == string(v1.InferencePoolConditionAccepted) &&
+ cc.Reason == string(InferencePoolReasonAccepted) {
+ cc.Reason = string(v1.InferencePoolReasonAccepted)
+ }
+ ps.Conditions = append(ps.Conditions, cc)
+ }
+ out.Parents = append(out.Parents, ps)
}
- return convert[v1.InferencePoolStatus](u)
+ return out, nil
}
func convertStatusFromV1(src *v1.InferencePoolStatus) (*InferencePoolStatus, error) {
if src == nil {
return nil, errors.New("src cannot be nil")
}
- u, err := toUnstructured(src)
- if err != nil {
- return nil, err
+ out := &InferencePoolStatus{
+ Parents: make([]PoolStatus, 0, len(src.Parents)),
+ }
+ for _, p := range src.Parents {
+ ps := PoolStatus{
+ GatewayRef: fromV1ParentRef(p.ParentRef),
+ Conditions: make([]metav1.Condition, 0, len(p.Conditions)),
+ }
+ for _, c := range p.Conditions {
+ cc := c
+ // v1: "SupportedByParent" -> v1alpha2: "Accepted"
+ if cc.Type == string(v1.InferencePoolConditionAccepted) &&
+ cc.Reason == string(v1.InferencePoolReasonAccepted) {
+ cc.Reason = string(InferencePoolReasonAccepted)
+ }
+ ps.Conditions = append(ps.Conditions, cc)
+ }
+ out.Parents = append(out.Parents, ps)
}
- return convert[InferencePoolStatus](u)
+ return out, nil
+}
+
+func toV1ParentRef(in ParentGatewayReference) v1.ParentReference {
+ out := v1.ParentReference{
+ Name: v1.ObjectName(in.Name),
+ }
+ if in.Group != nil {
+ g := v1.Group(*in.Group)
+ out.Group = &g
+ }
+ if in.Kind != nil {
+ k := v1.Kind(*in.Kind)
+ out.Kind = &k
+ }
+ if in.Namespace != nil {
+ ns := v1.Namespace(*in.Namespace)
+ out.Namespace = &ns
+ }
+ return out
+}
+
+func fromV1ParentRef(in v1.ParentReference) ParentGatewayReference {
+ out := ParentGatewayReference{
+ Name: ObjectName(in.Name),
+ }
+ if in.Group != nil {
+ g := Group(*in.Group)
+ out.Group = &g
+ }
+ if in.Kind != nil {
+ k := Kind(*in.Kind)
+ out.Kind = &k
+ }
+ if in.Namespace != nil {
+ ns := Namespace(*in.Namespace)
+ out.Namespace = &ns
+ }
+ return out
}
func convertExtensionRefToV1(src *Extension) (v1.EndpointPickerRef, error) {
@@ -108,19 +187,17 @@ func convertExtensionRefToV1(src *Extension) (v1.EndpointPickerRef, error) {
return endpointPickerRef, errors.New("src cannot be nil")
}
if src.Group != nil {
- v1Group := v1.Group(*src.Group)
- endpointPickerRef.Group = &v1Group
+ endpointPickerRef.Group = ptr.To(v1.Group(*src.Group))
}
if src.Kind != nil {
- endpointPickerRef.Kind = v1.Kind(*src.Kind)
+ endpointPickerRef.Kind = ptr.To(v1.Kind(*src.Kind))
}
endpointPickerRef.Name = v1.ObjectName(src.Name)
if src.PortNumber != nil {
- v1PortNumber := v1.PortNumber(*src.PortNumber)
- endpointPickerRef.PortNumber = &v1PortNumber
+ endpointPickerRef.PortNumber = ptr.To(v1.PortNumber(*src.PortNumber))
}
if src.FailureMode != nil {
- endpointPickerRef.FailureMode = v1.ExtensionFailureMode(*src.FailureMode)
+ endpointPickerRef.FailureMode = ptr.To(v1.EndpointPickerFailureMode(*src.FailureMode))
}
return endpointPickerRef, nil
@@ -132,37 +209,17 @@ func convertEndpointPickerRefFromV1(src *v1.EndpointPickerRef) (Extension, error
return extension, errors.New("src cannot be nil")
}
if src.Group != nil {
- group := Group(*src.Group)
- extension.Group = &group
+ extension.Group = ptr.To(Group(*src.Group))
}
- if src.Kind != "" {
- kind := Kind(src.Kind)
- extension.Kind = &kind
+ if src.Kind != nil {
+ extension.Kind = ptr.To(Kind(*src.Kind))
}
extension.Name = ObjectName(src.Name)
if src.PortNumber != nil {
- portNumber := PortNumber(*src.PortNumber)
- extension.PortNumber = &portNumber
+ extension.PortNumber = ptr.To(PortNumber(*src.PortNumber))
}
- if src.FailureMode != "" {
- extensionFailureMode := ExtensionFailureMode(src.FailureMode)
- extension.FailureMode = &extensionFailureMode
+ if src.FailureMode != nil {
+ extension.FailureMode = ptr.To(ExtensionFailureMode(*src.FailureMode))
}
return extension, nil
}
-
-func toUnstructured(obj any) (*unstructured.Unstructured, error) {
- u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
- if err != nil {
- return nil, err
- }
- return &unstructured.Unstructured{Object: u}, nil
-}
-
-func convert[T any](u *unstructured.Unstructured) (*T, error) {
- var res T
- if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &res); err != nil {
- return nil, fmt.Errorf("error converting unstructured to T: %v", err)
- }
- return &res, nil
-}
diff --git a/apix/v1alpha2/inferencepool_conversion_test.go b/apix/v1alpha2/inferencepool_conversion_test.go
index 2c59fc632..5a828dc37 100644
--- a/apix/v1alpha2/inferencepool_conversion_test.go
+++ b/apix/v1alpha2/inferencepool_conversion_test.go
@@ -33,7 +33,7 @@ var (
v1Group = v1.Group("my-group")
v1Kind = v1.Kind("MyKind")
- v1FailureMode = v1.ExtensionFailureMode("Deny")
+ v1FailureMode = v1.EndpointPickerFailureMode("Deny")
v1PortNumber = v1.PortNumber(9000)
)
@@ -49,7 +49,7 @@ func TestInferencePoolConvertTo(t *testing.T) {
src: &InferencePool{
TypeMeta: metav1.TypeMeta{
Kind: "InferencePool",
- APIVersion: "inference.networking.x-k8s.io/v1alpha2",
+ APIVersion: GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool",
@@ -87,7 +87,7 @@ func TestInferencePoolConvertTo(t *testing.T) {
want: &v1.InferencePool{
TypeMeta: metav1.TypeMeta{
Kind: "InferencePool",
- APIVersion: "inference.networking.x-k8s.io/v1alpha2",
+ APIVersion: v1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool",
@@ -102,16 +102,16 @@ func TestInferencePoolConvertTo(t *testing.T) {
TargetPorts: []v1.Port{{Number: v1.PortNumber(int32(8080))}},
EndpointPickerRef: v1.EndpointPickerRef{
Group: &v1Group,
- Kind: v1Kind,
+ Kind: &v1Kind,
Name: "my-epp-service",
PortNumber: &v1PortNumber,
- FailureMode: v1FailureMode,
+ FailureMode: &v1FailureMode,
},
},
Status: v1.InferencePoolStatus{
- Parents: []v1.PoolStatus{
+ Parents: []v1.ParentStatus{
{
- GatewayRef: v1.ParentGatewayReference{Name: "my-gateway"},
+ ParentRef: v1.ParentReference{Name: "my-gateway"},
Conditions: []metav1.Condition{
{
Type: string(v1.InferencePoolConditionAccepted),
@@ -131,7 +131,7 @@ func TestInferencePoolConvertTo(t *testing.T) {
src: &InferencePool{
TypeMeta: metav1.TypeMeta{
Kind: "InferencePool",
- APIVersion: "inference.networking.x-k8s.io/v1alpha2",
+ APIVersion: GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool",
@@ -162,7 +162,7 @@ func TestInferencePoolConvertTo(t *testing.T) {
want: &v1.InferencePool{
TypeMeta: metav1.TypeMeta{
Kind: "InferencePool",
- APIVersion: "inference.networking.x-k8s.io/v1alpha2",
+ APIVersion: v1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool",
@@ -177,9 +177,9 @@ func TestInferencePoolConvertTo(t *testing.T) {
TargetPorts: []v1.Port{{Number: v1.PortNumber(int32(8080))}},
},
Status: v1.InferencePoolStatus{
- Parents: []v1.PoolStatus{
+ Parents: []v1.ParentStatus{
{
- GatewayRef: v1.ParentGatewayReference{Name: "my-gateway"},
+ ParentRef: v1.ParentReference{Name: "my-gateway"},
Conditions: []metav1.Condition{
{
Type: string(v1.InferencePoolConditionAccepted),
@@ -222,7 +222,7 @@ func TestInferencePoolConvertFrom(t *testing.T) {
src: &v1.InferencePool{
TypeMeta: metav1.TypeMeta{
Kind: "InferencePool",
- APIVersion: "inference.networking.k8s.io/v1",
+ APIVersion: v1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool",
@@ -237,16 +237,16 @@ func TestInferencePoolConvertFrom(t *testing.T) {
TargetPorts: []v1.Port{{Number: v1.PortNumber(int32(8080))}},
EndpointPickerRef: v1.EndpointPickerRef{
Group: &v1Group,
- Kind: v1Kind,
+ Kind: &v1Kind,
Name: "my-epp-service",
PortNumber: &v1PortNumber,
- FailureMode: v1FailureMode,
+ FailureMode: &v1FailureMode,
},
},
Status: v1.InferencePoolStatus{
- Parents: []v1.PoolStatus{
+ Parents: []v1.ParentStatus{
{
- GatewayRef: v1.ParentGatewayReference{Name: "my-gateway"},
+ ParentRef: v1.ParentReference{Name: "my-gateway"},
Conditions: []metav1.Condition{
{
Type: string(v1.InferencePoolConditionAccepted),
@@ -262,7 +262,7 @@ func TestInferencePoolConvertFrom(t *testing.T) {
want: &InferencePool{
TypeMeta: metav1.TypeMeta{
Kind: "InferencePool",
- APIVersion: "inference.networking.k8s.io/v1",
+ APIVersion: GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool",
@@ -304,7 +304,7 @@ func TestInferencePoolConvertFrom(t *testing.T) {
src: &v1.InferencePool{
TypeMeta: metav1.TypeMeta{
Kind: "InferencePool",
- APIVersion: "inference.networking.k8s.io/v1",
+ APIVersion: v1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool",
@@ -319,9 +319,9 @@ func TestInferencePoolConvertFrom(t *testing.T) {
TargetPorts: []v1.Port{{Number: v1.PortNumber(int32(8080))}},
},
Status: v1.InferencePoolStatus{
- Parents: []v1.PoolStatus{
+ Parents: []v1.ParentStatus{
{
- GatewayRef: v1.ParentGatewayReference{Name: "my-gateway"},
+ ParentRef: v1.ParentReference{Name: "my-gateway"},
Conditions: []metav1.Condition{
{
Type: string(v1.InferencePoolConditionAccepted),
@@ -337,7 +337,7 @@ func TestInferencePoolConvertFrom(t *testing.T) {
want: &InferencePool{
TypeMeta: metav1.TypeMeta{
Kind: "InferencePool",
- APIVersion: "inference.networking.k8s.io/v1",
+ APIVersion: GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "test-pool",
diff --git a/apix/v1alpha2/zz_generated.deepcopy.go b/apix/v1alpha2/zz_generated.deepcopy.go
index 5a71e7530..0249d442d 100644
--- a/apix/v1alpha2/zz_generated.deepcopy.go
+++ b/apix/v1alpha2/zz_generated.deepcopy.go
@@ -22,7 +22,7 @@ package v1alpha2
import (
"k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
+ runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
diff --git a/client-go/applyconfiguration/api/v1/endpointpickerref.go b/client-go/applyconfiguration/api/v1/endpointpickerref.go
index 8e82230bd..8a9991bc5 100644
--- a/client-go/applyconfiguration/api/v1/endpointpickerref.go
+++ b/client-go/applyconfiguration/api/v1/endpointpickerref.go
@@ -25,11 +25,11 @@ import (
// EndpointPickerRefApplyConfiguration represents a declarative configuration of the EndpointPickerRef type for use
// with apply.
type EndpointPickerRefApplyConfiguration struct {
- Group *apiv1.Group `json:"group,omitempty"`
- Kind *apiv1.Kind `json:"kind,omitempty"`
- Name *apiv1.ObjectName `json:"name,omitempty"`
- PortNumber *apiv1.PortNumber `json:"portNumber,omitempty"`
- FailureMode *apiv1.ExtensionFailureMode `json:"failureMode,omitempty"`
+ Group *apiv1.Group `json:"group,omitempty"`
+ Kind *apiv1.Kind `json:"kind,omitempty"`
+ Name *apiv1.ObjectName `json:"name,omitempty"`
+ PortNumber *apiv1.PortNumber `json:"portNumber,omitempty"`
+ FailureMode *apiv1.EndpointPickerFailureMode `json:"failureMode,omitempty"`
}
// EndpointPickerRefApplyConfiguration constructs a declarative configuration of the EndpointPickerRef type for use with
@@ -73,7 +73,7 @@ func (b *EndpointPickerRefApplyConfiguration) WithPortNumber(value apiv1.PortNum
// WithFailureMode sets the FailureMode field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the FailureMode field is set to the value of the last call.
-func (b *EndpointPickerRefApplyConfiguration) WithFailureMode(value apiv1.ExtensionFailureMode) *EndpointPickerRefApplyConfiguration {
+func (b *EndpointPickerRefApplyConfiguration) WithFailureMode(value apiv1.EndpointPickerFailureMode) *EndpointPickerRefApplyConfiguration {
b.FailureMode = &value
return b
}
diff --git a/client-go/applyconfiguration/api/v1/inferencepoolstatus.go b/client-go/applyconfiguration/api/v1/inferencepoolstatus.go
index 5c66e3464..499b77151 100644
--- a/client-go/applyconfiguration/api/v1/inferencepoolstatus.go
+++ b/client-go/applyconfiguration/api/v1/inferencepoolstatus.go
@@ -21,7 +21,7 @@ package v1
// InferencePoolStatusApplyConfiguration represents a declarative configuration of the InferencePoolStatus type for use
// with apply.
type InferencePoolStatusApplyConfiguration struct {
- Parents []PoolStatusApplyConfiguration `json:"parent,omitempty"`
+ Parents []ParentStatusApplyConfiguration `json:"parents,omitempty"`
}
// InferencePoolStatusApplyConfiguration constructs a declarative configuration of the InferencePoolStatus type for use with
@@ -33,7 +33,7 @@ func InferencePoolStatus() *InferencePoolStatusApplyConfiguration {
// WithParents adds the given value to the Parents field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Parents field.
-func (b *InferencePoolStatusApplyConfiguration) WithParents(values ...*PoolStatusApplyConfiguration) *InferencePoolStatusApplyConfiguration {
+func (b *InferencePoolStatusApplyConfiguration) WithParents(values ...*ParentStatusApplyConfiguration) *InferencePoolStatusApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithParents")
diff --git a/client-go/applyconfiguration/api/v1/parentgatewayreference.go b/client-go/applyconfiguration/api/v1/parentreference.go
similarity index 69%
rename from client-go/applyconfiguration/api/v1/parentgatewayreference.go
rename to client-go/applyconfiguration/api/v1/parentreference.go
index 5e23aebe6..2798f020f 100644
--- a/client-go/applyconfiguration/api/v1/parentgatewayreference.go
+++ b/client-go/applyconfiguration/api/v1/parentreference.go
@@ -22,25 +22,25 @@ import (
apiv1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
)
-// ParentGatewayReferenceApplyConfiguration represents a declarative configuration of the ParentGatewayReference type for use
+// ParentReferenceApplyConfiguration represents a declarative configuration of the ParentReference type for use
// with apply.
-type ParentGatewayReferenceApplyConfiguration struct {
+type ParentReferenceApplyConfiguration struct {
Group *apiv1.Group `json:"group,omitempty"`
Kind *apiv1.Kind `json:"kind,omitempty"`
Name *apiv1.ObjectName `json:"name,omitempty"`
Namespace *apiv1.Namespace `json:"namespace,omitempty"`
}
-// ParentGatewayReferenceApplyConfiguration constructs a declarative configuration of the ParentGatewayReference type for use with
+// ParentReferenceApplyConfiguration constructs a declarative configuration of the ParentReference type for use with
// apply.
-func ParentGatewayReference() *ParentGatewayReferenceApplyConfiguration {
- return &ParentGatewayReferenceApplyConfiguration{}
+func ParentReference() *ParentReferenceApplyConfiguration {
+ return &ParentReferenceApplyConfiguration{}
}
// WithGroup sets the Group field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Group field is set to the value of the last call.
-func (b *ParentGatewayReferenceApplyConfiguration) WithGroup(value apiv1.Group) *ParentGatewayReferenceApplyConfiguration {
+func (b *ParentReferenceApplyConfiguration) WithGroup(value apiv1.Group) *ParentReferenceApplyConfiguration {
b.Group = &value
return b
}
@@ -48,7 +48,7 @@ func (b *ParentGatewayReferenceApplyConfiguration) WithGroup(value apiv1.Group)
// WithKind sets the Kind field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Kind field is set to the value of the last call.
-func (b *ParentGatewayReferenceApplyConfiguration) WithKind(value apiv1.Kind) *ParentGatewayReferenceApplyConfiguration {
+func (b *ParentReferenceApplyConfiguration) WithKind(value apiv1.Kind) *ParentReferenceApplyConfiguration {
b.Kind = &value
return b
}
@@ -56,7 +56,7 @@ func (b *ParentGatewayReferenceApplyConfiguration) WithKind(value apiv1.Kind) *P
// WithName sets the Name field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Name field is set to the value of the last call.
-func (b *ParentGatewayReferenceApplyConfiguration) WithName(value apiv1.ObjectName) *ParentGatewayReferenceApplyConfiguration {
+func (b *ParentReferenceApplyConfiguration) WithName(value apiv1.ObjectName) *ParentReferenceApplyConfiguration {
b.Name = &value
return b
}
@@ -64,7 +64,7 @@ func (b *ParentGatewayReferenceApplyConfiguration) WithName(value apiv1.ObjectNa
// WithNamespace sets the Namespace field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Namespace field is set to the value of the last call.
-func (b *ParentGatewayReferenceApplyConfiguration) WithNamespace(value apiv1.Namespace) *ParentGatewayReferenceApplyConfiguration {
+func (b *ParentReferenceApplyConfiguration) WithNamespace(value apiv1.Namespace) *ParentReferenceApplyConfiguration {
b.Namespace = &value
return b
}
diff --git a/client-go/applyconfiguration/api/v1/poolstatus.go b/client-go/applyconfiguration/api/v1/parentstatus.go
similarity index 57%
rename from client-go/applyconfiguration/api/v1/poolstatus.go
rename to client-go/applyconfiguration/api/v1/parentstatus.go
index 6c582d8c8..5accb0f45 100644
--- a/client-go/applyconfiguration/api/v1/poolstatus.go
+++ b/client-go/applyconfiguration/api/v1/parentstatus.go
@@ -22,23 +22,23 @@ import (
metav1 "k8s.io/client-go/applyconfigurations/meta/v1"
)
-// PoolStatusApplyConfiguration represents a declarative configuration of the PoolStatus type for use
+// ParentStatusApplyConfiguration represents a declarative configuration of the ParentStatus type for use
// with apply.
-type PoolStatusApplyConfiguration struct {
- Conditions []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"`
- GatewayRef *ParentGatewayReferenceApplyConfiguration `json:"parentRef,omitempty"`
+type ParentStatusApplyConfiguration struct {
+ Conditions []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"`
+ ParentRef *ParentReferenceApplyConfiguration `json:"parentRef,omitempty"`
}
-// PoolStatusApplyConfiguration constructs a declarative configuration of the PoolStatus type for use with
+// ParentStatusApplyConfiguration constructs a declarative configuration of the ParentStatus type for use with
// apply.
-func PoolStatus() *PoolStatusApplyConfiguration {
- return &PoolStatusApplyConfiguration{}
+func ParentStatus() *ParentStatusApplyConfiguration {
+ return &ParentStatusApplyConfiguration{}
}
// WithConditions adds the given value to the Conditions field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Conditions field.
-func (b *PoolStatusApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *PoolStatusApplyConfiguration {
+func (b *ParentStatusApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *ParentStatusApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithConditions")
@@ -48,10 +48,10 @@ func (b *PoolStatusApplyConfiguration) WithConditions(values ...*metav1.Conditio
return b
}
-// WithGatewayRef sets the GatewayRef field in the declarative configuration to the given value
+// WithParentRef sets the ParentRef field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the GatewayRef field is set to the value of the last call.
-func (b *PoolStatusApplyConfiguration) WithGatewayRef(value *ParentGatewayReferenceApplyConfiguration) *PoolStatusApplyConfiguration {
- b.GatewayRef = value
+// If called multiple times, the ParentRef field is set to the value of the last call.
+func (b *ParentStatusApplyConfiguration) WithParentRef(value *ParentReferenceApplyConfiguration) *ParentStatusApplyConfiguration {
+ b.ParentRef = value
return b
}
diff --git a/client-go/applyconfiguration/utils.go b/client-go/applyconfiguration/utils.go
index 8a3b6b384..06626998d 100644
--- a/client-go/applyconfiguration/utils.go
+++ b/client-go/applyconfiguration/utils.go
@@ -44,10 +44,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &apiv1.InferencePoolStatusApplyConfiguration{}
case v1.SchemeGroupVersion.WithKind("LabelSelector"):
return &apiv1.LabelSelectorApplyConfiguration{}
- case v1.SchemeGroupVersion.WithKind("ParentGatewayReference"):
- return &apiv1.ParentGatewayReferenceApplyConfiguration{}
- case v1.SchemeGroupVersion.WithKind("PoolStatus"):
- return &apiv1.PoolStatusApplyConfiguration{}
+ case v1.SchemeGroupVersion.WithKind("ParentReference"):
+ return &apiv1.ParentReferenceApplyConfiguration{}
+ case v1.SchemeGroupVersion.WithKind("ParentStatus"):
+ return &apiv1.ParentStatusApplyConfiguration{}
case v1.SchemeGroupVersion.WithKind("Port"):
return &apiv1.PortApplyConfiguration{}
diff --git a/config/crd/bases/inference.networking.k8s.io_inferencepools.yaml b/config/crd/bases/inference.networking.k8s.io_inferencepools.yaml
index 9a2891478..2dec05cdb 100644
--- a/config/crd/bases/inference.networking.k8s.io_inferencepools.yaml
+++ b/config/crd/bases/inference.networking.k8s.io_inferencepools.yaml
@@ -41,17 +41,18 @@ spec:
metadata:
type: object
spec:
- description: InferencePoolSpec defines the desired state of InferencePool
+ description: Spec defines the desired state of the InferencePool.
properties:
endpointPickerRef:
- description: EndpointPickerRef configures an endpoint picker as an
- extension service.
+ description: |-
+ EndpointPickerRef is a reference to the Endpoint Picker extension and its
+ associated configuration.
properties:
failureMode:
default: FailClose
description: |-
- Configures how the gateway handles the case when the extension is not responsive.
- Defaults to failClose.
+ FailureMode configures how the parent handles the case when the Endpoint Picker extension
+ is non-responsive. When unspecified, defaults to "FailClose".
enum:
- FailOpen
- FailClose
@@ -59,8 +60,8 @@ spec:
group:
default: ""
description: |-
- Group is the group of the referent.
- The default value is "", representing the Core API group.
+ Group is the group of the referent API object. When unspecified, the default value
+ is "", representing the Core API group.
maxLength: 253
minLength: 0
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
@@ -70,7 +71,7 @@ spec:
description: |-
Kind is the Kubernetes resource kind of the referent.
- Required if the referent is ambiguous(e.g. service with one port is unambiguous).
+ Required if the referent is ambiguous, e.g. service with multiple ports.
Defaults to "Service" when not specified.
@@ -84,15 +85,15 @@ spec:
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
- description: Name is the name of the referent.
+ description: Name is the name of the referent API object.
maxLength: 253
minLength: 1
type: string
portNumber:
description: |-
- The port number on the service running the extension. When unspecified,
- implementations SHOULD infer a default value of 9002 when the Kind is
- Service.
+ PortNumber is the port number of the Endpoint Picker extension service. When unspecified,
+ implementations SHOULD infer a default value of 9002 when the kind field is "Service" or
+ unspecified (defaults to "Service").
format: int32
maximum: 65535
minimum: 1
@@ -129,7 +130,7 @@ spec:
pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$
type: string
description: |-
- matchLabels contains a set of required {key,value} pairs.
+ MatchLabels contains a set of required {key,value} pairs.
An object must match every label in this map to be selected.
The matching logic is an AND operation on all entries.
type: object
@@ -165,48 +166,30 @@ spec:
- targetPorts
type: object
status:
- default:
- parent:
- - conditions:
- - lastTransitionTime: "1970-01-01T00:00:00Z"
- message: Waiting for controller
- reason: Pending
- status: Unknown
- type: Accepted
- parentRef:
- kind: Status
- name: default
- description: Status defines the observed state of InferencePool.
- minProperties: 1
+ description: Status defines the observed state of the InferencePool.
properties:
- parent:
+ parents:
description: |-
- Parents is a list of parent resources (usually Gateways) that are
- associated with the InferencePool, and the status of the InferencePool with respect to
- each parent.
+ Parents is a list of parent resources, typically Gateways, that are associated with
+ the InferencePool, and the status of the InferencePool with respect to each parent.
- A maximum of 32 Gateways will be represented in this list. When the list contains
- `kind: Status, name: default`, it indicates that the InferencePool is not
- associated with any Gateway and a controller must perform the following:
+ A controller that manages the InferencePool, must add an entry for each parent it manages
+ and remove the parent entry when the controller no longer considers the InferencePool to
+ be associated with that parent.
- - Remove the parent when setting the "Accepted" condition.
- - Add the parent when the controller will no longer manage the InferencePool
- and no other parents exist.
+ A maximum of 32 parents will be represented in this list. When the list is empty,
+ it indicates that the InferencePool is not associated with any parents.
items:
- description: PoolStatus defines the observed state of InferencePool
- from a Gateway.
+ description: ParentStatus defines the observed state of InferencePool
+ from a Parent, i.e. Gateway.
properties:
conditions:
- default:
- - lastTransitionTime: "1970-01-01T00:00:00Z"
- message: Waiting for controller
- reason: Pending
- status: Unknown
- type: Accepted
description: |-
- Conditions track the state of the InferencePool.
+ Conditions is a list of status conditions that provide information about the observed
+ state of the InferencePool. This field is required to be set by the controller that
+ manages the InferencePool.
- Known condition types are:
+ Supported condition types are:
* "Accepted"
* "ResolvedRefs"
@@ -271,33 +254,43 @@ spec:
- type
x-kubernetes-list-type: map
parentRef:
- description: GatewayRef indicates the gateway that observed
- state of InferencePool.
+ description: |-
+ ParentRef is used to identify the parent resource that this status
+ is associated with. It is used to match the InferencePool with the parent
+ resource, such as a Gateway.
properties:
group:
default: gateway.networking.k8s.io
- description: Group is the group of the referent.
+ description: |-
+ Group is the group of the referent API object. When unspecified, the referent is assumed
+ to be in the "gateway.networking.k8s.io" API group.
maxLength: 253
minLength: 0
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Gateway
- description: Kind is kind of the referent. For example "Gateway".
+ description: |-
+ Kind is the kind of the referent API object. When unspecified, the referent is assumed
+ to be a "Gateway" kind.
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
- description: Name is the name of the referent.
+ description: Name is the name of the referent API object.
maxLength: 253
minLength: 1
type: string
namespace:
description: |-
- Namespace is the namespace of the referent. If not present,
- the namespace of the referent is assumed to be the same as
- the namespace of the referring object.
+ Namespace is the namespace of the referenced object. When unspecified, the local
+ namespace is inferred.
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details: https://gateway-api.sigs.k8s.io/api-types/referencegrant/
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
diff --git a/conformance/utils/kubernetes/helpers.go b/conformance/utils/kubernetes/helpers.go
index 39301e342..fe0168ad4 100644
--- a/conformance/utils/kubernetes/helpers.go
+++ b/conformance/utils/kubernetes/helpers.go
@@ -32,6 +32,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
+ "k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
gatewayapiconfig "sigs.k8s.io/gateway-api/conformance/utils/config"
@@ -105,7 +106,9 @@ func InferencePoolMustHaveCondition(t *testing.T, c client.Reader, poolNN types.
}
for _, parentStatus := range pool.Status.Parents {
- if string(parentStatus.GatewayRef.Namespace) == gateway.Namespace && string(parentStatus.GatewayRef.Name) == gateway.Name {
+ if parentStatus.ParentRef.Namespace != nil &&
+ string(*parentStatus.ParentRef.Namespace) == gateway.Namespace &&
+ string(parentStatus.ParentRef.Name) == gateway.Name {
if checkCondition(t, parentStatus.Conditions, expectedCondition) {
conditionFound = true
return true, nil
@@ -130,8 +133,11 @@ func InferencePoolMustHaveCondition(t *testing.T, c client.Reader, poolNN types.
debugMsg += " (No parent statuses reported)"
}
for i, parentStatus := range lastObservedPool.Status.Parents {
- namespace := parentStatus.GatewayRef.Namespace
- debugMsg += fmt.Sprintf("\n Parent %d (Gateway: %s/%s):", i, namespace, parentStatus.GatewayRef.Name)
+ namespace := parentStatus.ParentRef.Namespace
+ if namespace == nil {
+ namespace = ptr.To(inferenceapi.Namespace(poolNN.Namespace)) // Fallback to the pool's namespace
+ }
+ debugMsg += fmt.Sprintf("\n Parent %d (Gateway: %s/%s):", i, *namespace, parentStatus.ParentRef.Name)
if len(parentStatus.Conditions) == 0 {
debugMsg += " (No conditions reported for this parent)"
}
diff --git a/site-src/reference/spec.md b/site-src/reference/spec.md
index 9b31f4470..a06968b29 100644
--- a/site-src/reference/spec.md
+++ b/site-src/reference/spec.md
@@ -15,43 +15,44 @@ inference.networking.k8s.io API group.
-#### Extension
+#### EndpointPickerFailureMode
+_Underlying type:_ _string_
+EndpointPickerFailureMode defines the options for how the parent handles the case when the
+Endpoint Picker extension is non-responsive.
-Extension specifies how to configure an extension that runs the endpoint picker.
+_Validation:_
+- Enum: [FailOpen FailClose]
+_Appears in:_
+- [EndpointPickerRef](#endpointpickerref)
+| Field | Description |
+| --- | --- |
+| `FailOpen` | EndpointPickerFailOpen specifies that the parent should forward the request to an endpoint
of its picking when the Endpoint Picker extension fails.
|
+| `FailClose` | EndpointPickerFailClose specifies that the parent should drop the request when the Endpoint
Picker extension fails.
|
-_Appears in:_
-- [InferencePoolSpec](#inferencepoolspec)
-| Field | Description | Default | Validation |
-| --- | --- | --- | --- |
-| `group` _[Group](#group)_ | Group is the group of the referent.
The default value is "", representing the Core API group. | | MaxLength: 253
MinLength: 0
Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
-| `kind` _[Kind](#kind)_ | Kind is the Kubernetes resource kind of the referent.
Defaults to "Service" when not specified.
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations MUST NOT
support ExternalName Services. | Service | MaxLength: 63
MinLength: 1
Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$`
|
-| `name` _[ObjectName](#objectname)_ | Name is the name of the referent. | | MaxLength: 253
MinLength: 1
|
-| `portNumber` _[PortNumber](#portnumber)_ | The port number on the service running the extension. When unspecified,
implementations SHOULD infer a default value of 9002 when the Kind is
Service. | | Maximum: 65535
Minimum: 1
|
-| `failureMode` _[ExtensionFailureMode](#extensionfailuremode)_ | Configures how the gateway handles the case when the extension is not responsive.
Defaults to failClose. | FailClose | Enum: [FailOpen FailClose]
|
+#### EndpointPickerRef
-#### ExtensionFailureMode
-_Underlying type:_ _string_
+EndpointPickerRef specifies a reference to an Endpoint Picker extension and its
+associated configuration.
-ExtensionFailureMode defines the options for how the gateway handles the case when the extension is not
-responsive.
-_Validation:_
-- Enum: [FailOpen FailClose]
_Appears in:_
-- [Extension](#extension)
+- [InferencePoolSpec](#inferencepoolspec)
-| Field | Description |
-| --- | --- |
-| `FailOpen` | FailOpen specifies that the proxy should forward the request to an endpoint of its picking when the Endpoint Picker fails.
|
-| `FailClose` | FailClose specifies that the proxy should drop the request when the Endpoint Picker fails.
|
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `group` _[Group](#group)_ | Group is the group of the referent API object. When unspecified, the default value
is "", representing the Core API group. | | MaxLength: 253
MinLength: 0
Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
+| `kind` _[Kind](#kind)_ | Kind is the Kubernetes resource kind of the referent API object. When unspecified,
the referent is assumed to be a "Service" kind.
ExternalName services can refer to CNAME DNS records that may live
outside of the cluster and as such are difficult to reason about in
terms of conformance. They also may not be safe to forward to (see
CVE-2021-25740 for more information). Implementations MUST NOT
support ExternalName Services. | Service | MaxLength: 63
MinLength: 1
Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$`
|
+| `name` _[ObjectName](#objectname)_ | Name is the name of the referent API object. | | MaxLength: 253
MinLength: 1
|
+| `portNumber` _[PortNumber](#portnumber)_ | PortNumber is the port number of the Endpoint Picker extension service. When unspecified,
implementations SHOULD infer a default value of 9002 when the kind field is "Service" or
unspecified (defaults to "Service"). | | Maximum: 65535
Minimum: 1
|
+| `failureMode` _[EndpointPickerFailureMode](#endpointpickerfailuremode)_ | FailureMode configures how the parent handles the case when the Endpoint Picker extension
is non-responsive. When unspecified, defaults to "FailClose". | FailClose | Enum: [FailOpen FailClose]
|
#### Group
@@ -80,8 +81,8 @@ _Validation:_
- Pattern: `^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
_Appears in:_
-- [Extension](#extension)
-- [ParentGatewayReference](#parentgatewayreference)
+- [EndpointPickerRef](#endpointpickerref)
+- [ParentReference](#parentreference)
@@ -101,8 +102,8 @@ InferencePool is the Schema for the InferencePools API.
| `apiVersion` _string_ | `inference.networking.k8s.io/v1` | | |
| `kind` _string_ | `InferencePool` | | |
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | |
-| `spec` _[InferencePoolSpec](#inferencepoolspec)_ | | | |
-| `status` _[InferencePoolStatus](#inferencepoolstatus)_ | Status defines the observed state of InferencePool. | \{ parent:[map[conditions:[map[lastTransitionTime:1970-01-01T00:00:00Z message:Waiting for controller reason:Pending status:Unknown type:Accepted]] parentRef:map[kind:Status name:default]]] \} | MinProperties: 1
|
+| `spec` _[InferencePoolSpec](#inferencepoolspec)_ | Spec defines the desired state of the InferencePool. | | |
+| `status` _[InferencePoolStatus](#inferencepoolstatus)_ | Status defines the observed state of the InferencePool. | | |
@@ -113,7 +114,7 @@ InferencePool is the Schema for the InferencePools API.
-InferencePoolSpec defines the desired state of InferencePool
+InferencePoolSpec defines the desired state of the InferencePool.
@@ -124,24 +125,23 @@ _Appears in:_
| --- | --- | --- | --- |
| `selector` _[LabelSelector](#labelselector)_ | Selector determines which Pods are members of this inference pool.
It matches Pods by their labels only within the same namespace; cross-namespace
selection is not supported.
The structure of this LabelSelector is intentionally simple to be compatible
with Kubernetes Service selectors, as some implementations may translate
this configuration into a Service resource. | | |
| `targetPorts` _[Port](#port) array_ | TargetPorts defines a list of ports that are exposed by this InferencePool.
Currently, the list may only include a single port definition. | | MaxItems: 1
MinItems: 1
|
-| `extensionRef` _[Extension](#extension)_ | Extension configures an endpoint picker as an extension service. | | |
+| `endpointPickerRef` _[EndpointPickerRef](#endpointpickerref)_ | EndpointPickerRef is a reference to the Endpoint Picker extension and its
associated configuration. | | |
#### InferencePoolStatus
-InferencePoolStatus defines the observed state of InferencePool.
+InferencePoolStatus defines the observed state of the InferencePool.
+
-_Validation:_
-- MinProperties: 1
_Appears in:_
- [InferencePool](#inferencepool)
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `parent` _[PoolStatus](#poolstatus) array_ | Parents is a list of parent resources (usually Gateways) that are
associated with the InferencePool, and the status of the InferencePool with respect to
each parent.
A maximum of 32 Gateways will be represented in this list. When the list contains
`kind: Status, name: default`, it indicates that the InferencePool is not
associated with any Gateway and a controller must perform the following:
- Remove the parent when setting the "Accepted" condition.
- Add the parent when the controller will no longer manage the InferencePool
and no other parents exist. | | MaxItems: 32
|
+| `parents` _[ParentStatus](#parentstatus) array_ | Parents is a list of parent resources, typically Gateways, that are associated with
the InferencePool, and the status of the InferencePool with respect to each parent.
A controller that manages the InferencePool, must add an entry for each parent it manages
and remove the parent entry when the controller no longer considers the InferencePool to
be associated with that parent.
A maximum of 32 parents will be represented in this list. When the list is empty,
it indicates that the InferencePool is not associated with any parents. | | MaxItems: 32
|
#### Kind
@@ -165,8 +165,8 @@ _Validation:_
- Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$`
_Appears in:_
-- [Extension](#extension)
-- [ParentGatewayReference](#parentgatewayreference)
+- [EndpointPickerRef](#endpointpickerref)
+- [ParentReference](#parentreference)
@@ -217,7 +217,7 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `matchLabels` _object (keys:[LabelKey](#labelkey), values:[LabelValue](#labelvalue))_ | matchLabels contains a set of required \{key,value\} pairs.
An object must match every label in this map to be selected.
The matching logic is an AND operation on all entries. | | MaxItems: 64
|
+| `matchLabels` _object (keys:[LabelKey](#labelkey), values:[LabelValue](#labelvalue))_ | MatchLabels contains a set of required \{key,value\} pairs.
An object must match every label in this map to be selected.
The matching logic is an AND operation on all entries. | | MaxItems: 64
MinItems: 1
|
#### LabelValue
@@ -272,7 +272,7 @@ _Validation:_
- Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
_Appears in:_
-- [ParentGatewayReference](#parentgatewayreference)
+- [ParentReference](#parentreference)
@@ -289,36 +289,36 @@ _Validation:_
- MinLength: 1
_Appears in:_
-- [Extension](#extension)
-- [ParentGatewayReference](#parentgatewayreference)
+- [EndpointPickerRef](#endpointpickerref)
+- [ParentReference](#parentreference)
-#### ParentGatewayReference
+#### ParentReference
-ParentGatewayReference identifies an API object including its namespace,
-defaulting to Gateway.
+ParentReference identifies an API object. It is used to associate the InferencePool with a
+parent resource, such as a Gateway.
_Appears in:_
-- [PoolStatus](#poolstatus)
+- [ParentStatus](#parentstatus)
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `group` _[Group](#group)_ | Group is the group of the referent. | gateway.networking.k8s.io | MaxLength: 253
MinLength: 0
Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
-| `kind` _[Kind](#kind)_ | Kind is kind of the referent. For example "Gateway". | Gateway | MaxLength: 63
MinLength: 1
Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$`
|
-| `name` _[ObjectName](#objectname)_ | Name is the name of the referent. | | MaxLength: 253
MinLength: 1
|
-| `namespace` _[Namespace](#namespace)_ | Namespace is the namespace of the referent. If not present,
the namespace of the referent is assumed to be the same as
the namespace of the referring object. | | MaxLength: 63
MinLength: 1
Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
|
+| `group` _[Group](#group)_ | Group is the group of the referent API object. When unspecified, the referent is assumed
to be in the "gateway.networking.k8s.io" API group. | gateway.networking.k8s.io | MaxLength: 253
MinLength: 0
Pattern: `^$\|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
+| `kind` _[Kind](#kind)_ | Kind is the kind of the referent API object. When unspecified, the referent is assumed
to be a "Gateway" kind. | Gateway | MaxLength: 63
MinLength: 1
Pattern: `^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$`
|
+| `name` _[ObjectName](#objectname)_ | Name is the name of the referent API object. | | MaxLength: 253
MinLength: 1
|
+| `namespace` _[Namespace](#namespace)_ | Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.
Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details: https://gateway-api.sigs.k8s.io/api-types/referencegrant/ | | MaxLength: 63
MinLength: 1
Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
|
-#### PoolStatus
+#### ParentStatus
-PoolStatus defines the observed state of InferencePool from a Gateway.
+ParentStatus defines the observed state of InferencePool from a Parent, i.e. Gateway.
@@ -327,8 +327,8 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions track the state of the InferencePool.
Known condition types are:
* "Accepted"
* "ResolvedRefs" | [map[lastTransitionTime:1970-01-01T00:00:00Z message:Waiting for controller reason:Pending status:Unknown type:Accepted]] | MaxItems: 8
|
-| `parentRef` _[ParentGatewayReference](#parentgatewayreference)_ | GatewayRef indicates the gateway that observed state of InferencePool. | | |
+| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | Conditions is a list of status conditions that provide information about the observed
state of the InferencePool. This field is required to be set by the controller that
manages the InferencePool.
Supported condition types are:
* "Accepted"
* "ResolvedRefs" | | MaxItems: 8
|
+| `parentRef` _[ParentReference](#parentreference)_ | ParentRef is used to identify the parent resource that this status
is associated with. It is used to match the InferencePool with the parent
resource, such as a Gateway. | | |
#### Port
@@ -358,7 +358,7 @@ _Validation:_
- Minimum: 1
_Appears in:_
-- [Extension](#extension)
+- [EndpointPickerRef](#endpointpickerref)
- [Port](#port)