From 0da1861506af14284cca72e5f42fca46070afbd3 Mon Sep 17 00:00:00 2001 From: Nitishkumar Singh Date: Thu, 4 Dec 2025 09:38:47 +0530 Subject: [PATCH] inference extension support Signed-off-by: Nitishkumar Singh --- .../extension/inference/common.rs | 11 ++ .../inference/inferenceobjectives.rs | 81 +++++++++ .../extension/inference/inferencepools.rs | 134 ++++++++++++++ .../experimental/extension/inference/mod.rs | 5 + .../standard/extension/inference/common.rs | 15 ++ .../extension/inference/inferencepools.rs | 168 ++++++++++++++++++ .../apis/standard/extension/inference/mod.rs | 4 + .../experimental_customized_mapped_names.txt | 1 + .../experimental_reduced_types_pass_0.txt | 1 + .../experimental_rename_only_mapped_names.txt | 5 + .../standard_customized_mapped_names.txt | 3 + .../standard_reduced_types_pass_0.txt | 1 + .../standard_rename_only_mapped_names.txt | 5 + update.sh | 116 +++++++++++- xtask/src/main.rs | 59 +++--- 15 files changed, 579 insertions(+), 30 deletions(-) create mode 100644 gateway-api/src/apis/experimental/extension/inference/common.rs create mode 100644 gateway-api/src/apis/experimental/extension/inference/inferenceobjectives.rs create mode 100644 gateway-api/src/apis/experimental/extension/inference/inferencepools.rs create mode 100644 gateway-api/src/apis/experimental/extension/inference/mod.rs create mode 100644 gateway-api/src/apis/standard/extension/inference/common.rs create mode 100644 gateway-api/src/apis/standard/extension/inference/inferencepools.rs create mode 100644 gateway-api/src/apis/standard/extension/inference/mod.rs create mode 100644 type-reducer/extension/inference/experimental_customized_mapped_names.txt create mode 100644 type-reducer/extension/inference/experimental_reduced_types_pass_0.txt create mode 100644 type-reducer/extension/inference/experimental_rename_only_mapped_names.txt create mode 100644 type-reducer/extension/inference/standard_customized_mapped_names.txt create mode 100644 type-reducer/extension/inference/standard_reduced_types_pass_0.txt create mode 100644 type-reducer/extension/inference/standard_rename_only_mapped_names.txt diff --git a/gateway-api/src/apis/experimental/extension/inference/common.rs b/gateway-api/src/apis/experimental/extension/inference/common.rs new file mode 100644 index 0000000..cdaf5e6 --- /dev/null +++ b/gateway-api/src/apis/experimental/extension/inference/common.rs @@ -0,0 +1,11 @@ +// WARNING: generated file - manual changes will be overriden + +#[allow(unused_imports)] +mod prelude { + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; + pub use kube_derive::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Deserialize, Serialize}; + pub use std::collections::BTreeMap; +} +use self::prelude::*; diff --git a/gateway-api/src/apis/experimental/extension/inference/inferenceobjectives.rs b/gateway-api/src/apis/experimental/extension/inference/inferenceobjectives.rs new file mode 100644 index 0000000..130b9c8 --- /dev/null +++ b/gateway-api/src/apis/experimental/extension/inference/inferenceobjectives.rs @@ -0,0 +1,81 @@ +// WARNING: generated file - manual changes will be overriden + +#[allow(unused_imports)] +mod prelude { + pub use kube_derive::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Serialize, Deserialize}; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; +/// InferenceObjectiveSpec represents the desired state of a specific model use case. This resource is +/// managed by the "Inference Workload Owner" persona. +/// +/// The Inference Workload Owner persona is someone that trains, verifies, and +/// leverages a large language model from a model frontend, drives the lifecycle +/// and rollout of new versions of those models, and defines the specific +/// performance and latency goals for the model. These workloads are +/// expected to operate within an InferencePool sharing compute capacity with other +/// InferenceObjectives, defined by the Inference Platform Admin. +#[derive( + CustomResource, + Serialize, + Deserialize, + Clone, + Debug, + JsonSchema, + Default, + PartialEq +)] +#[kube( + group = "inference.networking.x-k8s.io", + version = "v1alpha2", + kind = "InferenceObjective", + plural = "inferenceobjectives" +)] +#[kube(namespaced)] +#[kube(status = "InferenceObjectiveStatus")] +#[kube(derive = "Default")] +#[kube(derive = "PartialEq")] +pub struct InferenceObjectiveSpec { + /// PoolRef is a reference to the inference pool, the pool must exist in the same namespace. + #[serde(rename = "poolRef")] + pub pool_ref: InferenceObjectivePoolRef, + /// Priority defines how important it is to serve the request compared to other requests in the same pool. + /// Priority is an integer value that defines the priority of the request. + /// The higher the value, the more critical the request is; negative values _are_ allowed. + /// No default value is set for this field, allowing for future additions of new fields that may 'one of' with this field. + /// However, implementations that consume this field (such as the Endpoint Picker) will treat an unset value as '0'. + /// Priority is used in flow control, primarily in the event of resource scarcity(requests need to be queued). + /// All requests will be queued, and flow control will _always_ allow requests of higher priority to be served first. + /// Fairness is only enforced and tracked between requests of the same priority. + /// + /// Example: requests with Priority 10 will always be served before + /// requests with Priority of 0 (the value used if Priority is unset or no InfereneceObjective is specified). + /// Similarly requests with a Priority of -10 will always be served after requests with Priority of 0. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub priority: Option, +} +/// PoolRef is a reference to the inference pool, the pool must exist in the same namespace. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct InferenceObjectivePoolRef { + /// Group is the group of the referent. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub group: Option, + /// Kind is kind of the referent. For example "InferencePool". + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + /// Name is the name of the referent. + pub name: String, +} +/// InferenceObjectiveStatus defines the observed state of InferenceObjective +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct InferenceObjectiveStatus { + /// Conditions track the state of the InferenceObjective. + /// + /// Known condition types are: + /// + /// * "Accepted" + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, +} diff --git a/gateway-api/src/apis/experimental/extension/inference/inferencepools.rs b/gateway-api/src/apis/experimental/extension/inference/inferencepools.rs new file mode 100644 index 0000000..83063e8 --- /dev/null +++ b/gateway-api/src/apis/experimental/extension/inference/inferencepools.rs @@ -0,0 +1,134 @@ +// WARNING: generated file - manual changes will be overriden + +use super::common::*; +#[allow(unused_imports)] +mod prelude { + pub use kube_derive::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; +/// InferencePoolSpec defines the desired state of InferencePool +#[derive( + CustomResource, + Serialize, + Deserialize, + Clone, + Debug, + JsonSchema, + Default, + PartialEq +)] +#[kube( + group = "inference.networking.x-k8s.io", + version = "v1alpha2", + kind = "InferencePool", + plural = "inferencepools" +)] +#[kube(namespaced)] +#[kube(status = "InferencePoolStatus")] +#[kube(derive = "Default")] +#[kube(derive = "PartialEq")] +pub struct InferencePoolSpec { + /// Extension configures an endpoint picker as an extension service. + #[serde(rename = "extensionRef")] + pub extension_ref: ExtensionRef, + /// Selector defines a map of labels to watch model server Pods + /// that should be included in the InferencePool. + /// In some cases, implementations may translate this field to a Service selector, so this matches the simple + /// map used for Service selectors instead of the full Kubernetes LabelSelector type. + /// If specified, it will be applied to match the model server pods in the same namespace as the InferencePool. + /// Cross namesoace selector is not supported. + pub selector: BTreeMap, + /// TargetPortNumber defines the port number to access the selected model server Pods. + /// The number must be in the range 1 to 65535. + #[serde(rename = "targetPortNumber")] + pub target_port_number: i32, +} +/// Extension configures an endpoint picker as an extension service. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct ExtensionRef { + /// Configures how the gateway handles the case when the extension is not responsive. + /// Defaults to failClose. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "failureMode")] + pub failure_mode: Option, + /// Group is the group of the referent. + /// The default value is "", representing the Core API group. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub group: Option, + /// 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. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + /// Name is the name of the referent. + pub name: String, + /// The port number on the service running the extension. When unspecified, + /// implementations SHOULD infer a default value of 9002 when the Kind is + /// Service. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "portNumber")] + pub port_number: Option, +} +/// Extension configures an endpoint picker as an extension service. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, PartialEq)] +pub enum ExtensionFailureMode { + FailOpen, + FailClose, +} +/// Status defines the observed state of InferencePool. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct InferencePoolStatus { + /// 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. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parent: Option>, +} +/// PoolStatus defines the observed state of InferencePool from a Gateway. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct InferencePoolParent { + /// Conditions track the state of the InferencePool. + /// + /// Known condition types are: + /// + /// * "Accepted" + /// * "ResolvedRefs" + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, + /// GatewayRef indicates the gateway that observed state of InferencePool. + #[serde(rename = "parentRef")] + pub parent_ref: ParentRef, +} +/// GatewayRef indicates the gateway that observed state of InferencePool. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct ParentRef { + /// Group is the group of the referent. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub group: Option, + /// Kind is kind of the referent. For example "Gateway". + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + /// Name is the name of the referent. + pub name: String, + /// 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. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} diff --git a/gateway-api/src/apis/experimental/extension/inference/mod.rs b/gateway-api/src/apis/experimental/extension/inference/mod.rs new file mode 100644 index 0000000..cbccce9 --- /dev/null +++ b/gateway-api/src/apis/experimental/extension/inference/mod.rs @@ -0,0 +1,5 @@ +// WARNING: generated file - manual changes will be overriden + +pub mod common; +pub mod inferenceobjectives; +pub mod inferencepools; diff --git a/gateway-api/src/apis/standard/extension/inference/common.rs b/gateway-api/src/apis/standard/extension/inference/common.rs new file mode 100644 index 0000000..5ffd87f --- /dev/null +++ b/gateway-api/src/apis/standard/extension/inference/common.rs @@ -0,0 +1,15 @@ +// WARNING: generated file - manual changes will be overriden + +#[allow(unused_imports)] +mod prelude { + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; + pub use kube_derive::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Deserialize, Serialize}; + pub use std::collections::BTreeMap; +} +use self::prelude::*; +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct EndPointPort { + pub number: i32, +} diff --git a/gateway-api/src/apis/standard/extension/inference/inferencepools.rs b/gateway-api/src/apis/standard/extension/inference/inferencepools.rs new file mode 100644 index 0000000..94e9dac --- /dev/null +++ b/gateway-api/src/apis/standard/extension/inference/inferencepools.rs @@ -0,0 +1,168 @@ +// WARNING: generated file - manual changes will be overriden + +use super::common::*; +#[allow(unused_imports)] +mod prelude { + pub use kube_derive::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; +/// Spec defines the desired state of the InferencePool. +#[derive( + CustomResource, + Serialize, + Deserialize, + Clone, + Debug, + JsonSchema, + Default, + PartialEq +)] +#[kube( + group = "inference.networking.k8s.io", + version = "v1", + kind = "InferencePool", + plural = "inferencepools" +)] +#[kube(namespaced)] +#[kube(status = "InferencePoolStatus")] +#[kube(derive = "Default")] +#[kube(derive = "PartialEq")] +pub struct InferencePoolSpec { + /// EndpointPickerRef is a reference to the Endpoint Picker extension and its + /// associated configuration. + #[serde(rename = "endpointPickerRef")] + pub endpoint_picker_ref: ExtensionRef, + /// 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. + pub selector: InferencePoolSelector, + /// TargetPorts defines a list of ports that are exposed by this InferencePool. + /// Currently, the list may only include a single port definition. + #[serde(rename = "targetPorts")] + pub target_ports: Vec, +} +/// EndpointPickerRef is a reference to the Endpoint Picker extension and its +/// associated configuration. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct ExtensionRef { + /// FailureMode configures how the parent handles the case when the Endpoint Picker extension + /// is non-responsive. When unspecified, defaults to "FailClose". + #[serde(default, skip_serializing_if = "Option::is_none", rename = "failureMode")] + pub failure_mode: Option, + /// Group is the group of the referent API object. When unspecified, the default value + /// is "", representing the Core API group. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub group: Option, + /// Kind is the Kubernetes resource kind of the referent. + /// + /// Required if the referent is ambiguous, e.g. service with multiple ports. + /// + /// 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. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + /// Name is the name of the referent API object. + pub name: String, + /// Port is the port of the Endpoint Picker extension service. + /// + /// Port is required when the referent is a Kubernetes Service. In this + /// case, the port number is the service port number, not the target port. + /// For other resources, destination port might be derived from the referent + /// resource or this field. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub port: Option, +} +/// EndpointPickerRef is a reference to the Endpoint Picker extension and its +/// associated configuration. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, PartialEq)] +pub enum ExtensionFailureMode { + FailOpen, + FailClose, +} +/// 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. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct InferencePoolSelector { + /// 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. + #[serde(rename = "matchLabels")] + pub match_labels: BTreeMap, +} +/// Status defines the observed state of the InferencePool. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct InferencePoolStatus { + /// 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. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parents: Option>, +} +/// ParentStatus defines the observed state of InferencePool from a Parent, i.e. Gateway. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct InferencePoolParent { + /// 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" + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, + /// 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. + #[serde(rename = "parentRef")] + pub parent_ref: ParentRef, +} +/// 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. +#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema, Default, PartialEq)] +pub struct ParentRef { + /// 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. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub group: Option, + /// Kind is the kind of the referent API object. When unspecified, the referent is assumed + /// to be a "Gateway" kind. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + /// Name is the name of the referent API object. + pub name: String, + /// 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: + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} diff --git a/gateway-api/src/apis/standard/extension/inference/mod.rs b/gateway-api/src/apis/standard/extension/inference/mod.rs new file mode 100644 index 0000000..c7b2180 --- /dev/null +++ b/gateway-api/src/apis/standard/extension/inference/mod.rs @@ -0,0 +1,4 @@ +// WARNING: generated file - manual changes will be overriden + +pub mod common; +pub mod inferencepools; diff --git a/type-reducer/extension/inference/experimental_customized_mapped_names.txt b/type-reducer/extension/inference/experimental_customized_mapped_names.txt new file mode 100644 index 0000000..0bd8d35 --- /dev/null +++ b/type-reducer/extension/inference/experimental_customized_mapped_names.txt @@ -0,0 +1 @@ +#### Pass 1 \ No newline at end of file diff --git a/type-reducer/extension/inference/experimental_reduced_types_pass_0.txt b/type-reducer/extension/inference/experimental_reduced_types_pass_0.txt new file mode 100644 index 0000000..3c2773d --- /dev/null +++ b/type-reducer/extension/inference/experimental_reduced_types_pass_0.txt @@ -0,0 +1 @@ +Condition \ No newline at end of file diff --git a/type-reducer/extension/inference/experimental_rename_only_mapped_names.txt b/type-reducer/extension/inference/experimental_rename_only_mapped_names.txt new file mode 100644 index 0000000..124edbe --- /dev/null +++ b/type-reducer/extension/inference/experimental_rename_only_mapped_names.txt @@ -0,0 +1,5 @@ +### Rename only +InferencePoolStatusParent->InferencePoolParent +InferencePoolStatusParentParentRef->ParentRef +InferencePoolExtensionRef->ExtensionRef +InferencePoolExtensionRefFailureMode->ExtensionFailureMode diff --git a/type-reducer/extension/inference/standard_customized_mapped_names.txt b/type-reducer/extension/inference/standard_customized_mapped_names.txt new file mode 100644 index 0000000..99016ef --- /dev/null +++ b/type-reducer/extension/inference/standard_customized_mapped_names.txt @@ -0,0 +1,3 @@ +#### Pass 1 +InferencePoolEndpointPickerRefPort->EndPointPort +InferencePoolTargetPorts->EndPointPort \ No newline at end of file diff --git a/type-reducer/extension/inference/standard_reduced_types_pass_0.txt b/type-reducer/extension/inference/standard_reduced_types_pass_0.txt new file mode 100644 index 0000000..3c2773d --- /dev/null +++ b/type-reducer/extension/inference/standard_reduced_types_pass_0.txt @@ -0,0 +1 @@ +Condition \ No newline at end of file diff --git a/type-reducer/extension/inference/standard_rename_only_mapped_names.txt b/type-reducer/extension/inference/standard_rename_only_mapped_names.txt new file mode 100644 index 0000000..0ebc961 --- /dev/null +++ b/type-reducer/extension/inference/standard_rename_only_mapped_names.txt @@ -0,0 +1,5 @@ +### Rename only +InferencePoolStatusParents->InferencePoolParent +InferencePoolStatusParentsParentRef->ParentRef +InferencePoolEndpointPickerRef->ExtensionRef +InferencePoolEndpointPickerRefFailureMode->ExtensionFailureMode \ No newline at end of file diff --git a/update.sh b/update.sh index c579005..01bc282 100755 --- a/update.sh +++ b/update.sh @@ -96,8 +96,8 @@ ENUMS=( ENUMS_WITH_DEFAULTS=$(printf ",%s" "${ENUMS[@]}") ENUMS_WITH_DEFAULTS=${ENUMS_WITH_DEFAULTS:1} -# The task searches for $GATEWAY_API_ENUMS in the environment to get the enum names and their default variants. -GATEWAY_API_ENUMS=${ENUMS_WITH_DEFAULTS} cargo xtask gen_enum_defaults >> $APIS_DIR/standard/enum_defaults.rs +# The task searches for $API_ENUMS in the environment to get the enum names and their default variants. +API_ENUMS=${ENUMS_WITH_DEFAULTS} cargo xtask gen_enum_defaults >> $APIS_DIR/standard/enum_defaults.rs echo "mod enum_defaults;" >> $APIS_DIR/standard/mod.rs GATEWAY_CLASS_CONDITION_CONSTANTS="GatewayClassConditionType=Accepted" @@ -141,7 +141,7 @@ ENUMS=( ENUMS_WITH_DEFAULTS=$(printf ",%s" "${ENUMS[@]}") ENUMS_WITH_DEFAULTS=${ENUMS_WITH_DEFAULTS:1} -GATEWAY_API_ENUMS=${ENUMS_WITH_DEFAULTS} cargo xtask gen_enum_defaults >> $APIS_DIR/experimental/enum_defaults.rs +API_ENUMS=${ENUMS_WITH_DEFAULTS} cargo xtask gen_enum_defaults >> $APIS_DIR/experimental/enum_defaults.rs echo "mod enum_defaults;" >> $APIS_DIR/experimental/mod.rs # GatewayClass conditions vary between standard and experimental @@ -189,7 +189,7 @@ ENUMS=( ENUMS_WITH_DEFAULTS=$(printf ",%s" "${ENUMS[@]}") ENUMS_WITH_DEFAULTS=${ENUMS_WITH_DEFAULTS:1} -GATEWAY_API_ENUMS=${ENUMS_WITH_DEFAULTS} cargo xtask gen_enum_defaults > $APIS_DIR/standard/enum_defaults.rs +API_ENUMS=${ENUMS_WITH_DEFAULTS} cargo xtask gen_enum_defaults > $APIS_DIR/standard/enum_defaults.rs sed -i '/#\[kube(status = "GrpcRouteStatus")\]/c\#\[kube(status = "RouteStatus")\]' $APIS_DIR/standard/grpcroutes.rs sed -i '/#\[kube(status = "HttpRouteStatus")\]/c\#\[kube(status = "RouteStatus")\]' $APIS_DIR/standard/httproutes.rs @@ -223,7 +223,7 @@ ENUMS=( ENUMS_WITH_DEFAULTS=$(printf ",%s" "${ENUMS[@]}") ENUMS_WITH_DEFAULTS=${ENUMS_WITH_DEFAULTS:1} -GATEWAY_API_ENUMS=${ENUMS_WITH_DEFAULTS} cargo xtask gen_enum_defaults > $APIS_DIR/experimental/enum_defaults.rs +API_ENUMS=${ENUMS_WITH_DEFAULTS} cargo xtask gen_enum_defaults > $APIS_DIR/experimental/enum_defaults.rs sed -i '/#\[kube(status = "GrpcRouteStatus")\]/c\#\[kube(status = "RouteStatus")\]' $APIS_DIR/experimental/grpcroutes.rs sed -i '/#\[kube(status = "HttpRouteStatus")\]/c\#\[kube(status = "RouteStatus")\]' $APIS_DIR/experimental/httproutes.rs @@ -232,9 +232,9 @@ sed -i '/#\[kube(status = "UdpRouteStatus")\]/c\#\[kube(status = "RouteStatus")\ sed -i '/#\[kube(status = "TcpRouteStatus")\]/c\#\[kube(status = "RouteStatus")\]' $APIS_DIR/experimental/tcproutes.rs cargo fmt -echo "API Generation complete" +echo "Gateway API Generation complete" -echo "Cleaning up temporary files" +echo "Gateway API Cleaning up temporary files" set -x rm -f standard_mapped_names_phase_*.txt rm -f standard_mapped_types_to_names_phase_*.txt @@ -243,4 +243,104 @@ rm -f experimental_mapped_types_to_names_phase_*.txt rm -f mapped_names.txt rm -f mapped_types_to_names.txt set +x -echo "Cleanup complete" +echo "Gateway API Cleanup complete" + + +# ------------------------------------------------------------------------------ +# Inference Extension +# ------------------------------------------------------------------------------ + +echo " **** Inference Extension Processing Starts **** " + +INFERENCE_EXT_VERSION="v1.0.2" +echo "Using Inference Extension version ${INFERENCE_EXT_VERSION}" + +INFERENCE_EXT_STANDARD_APIS=( + inferencepools +) + +INFERENCE_EXT_EXPERIMENTAL_APIS=( + inferencepools + inferenceobjectives +) + +mkdir -p $APIS_DIR/standard/extension/inference +mkdir -p $APIS_DIR/experimental/extension/inference + + +echo "// WARNING! generated file do not edit" > $APIS_DIR/standard/extension/inference/mod.rs + +for API in "${INFERENCE_EXT_STANDARD_APIS[@]}" +do + echo "generating inference extension standard api ${API}" + curl -sSL "https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/${INFERENCE_EXT_VERSION}/config/crd/bases/inference.networking.k8s.io_${API}.yaml" | kopium --schema=derived --derive=JsonSchema --derive=Default --derive=PartialEq --docs -f - > $APIS_DIR/standard/extension/inference/${API}.rs + sed -i 's/pub use kube::CustomResource;/pub use kube_derive::CustomResource;/g' $APIS_DIR/standard/extension/inference/${API}.rs + echo "pub mod ${API};" >> $APIS_DIR/standard/extension/inference/mod.rs +done + +# Standard API enums that need a Default trait impl along with their respective default variant. +# ENUMS=( +# InferencePoolEndpointPickerRefFailureMode=FailOpen +# ) + +# # Create a comma separated string out of $ENUMS. +# ENUMS_WITH_DEFAULTS=$(printf ",%s" "${ENUMS[@]}") +# ENUMS_WITH_DEFAULTS=${ENUMS_WITH_DEFAULTS:1} + +# # The task searches for $API_ENUMS in the environment to get the enum names and their default variants. +# API_ENUMS=${ENUMS_WITH_DEFAULTS} cargo xtask gen_enum_defaults >> $APIS_DIR/standard/extension/inference/enum_defaults.rs +# echo "mod enum_defaults;" >> $APIS_DIR/standard/extension/inference/mod.rs + +# EXT_INFERENCE_FAILURE_MODE_CONSTANTS="InferencePoolEndpointPickerRefFailureMode=FailOpen,FailClose" + +# EXT_INFERENCE_FAILURE_MODE_CONSTANTS=${EXT_INFERENCE_FAILURE_MODE_CONSTANTS} \ +# cargo xtask gen_condition_constants inference >> $APIS_DIR/standard/extension/inference/constants.rs +# echo "pub mod constants;" >> $APIS_DIR/standard/extension/inference/mod.rs + +echo "// WARNING! generated file do not edit" > $APIS_DIR/experimental/extension/inference/mod.rs + +for API in "${INFERENCE_EXT_EXPERIMENTAL_APIS[@]}" +do + echo "generating inference extension experimental api ${API}" + curl -sSL "https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/${INFERENCE_EXT_VERSION}/config/crd/bases/inference.networking.x-k8s.io_${API}.yaml" | kopium --schema=derived --derive=JsonSchema --derive=Default --derive=PartialEq --docs -f - > $APIS_DIR/experimental/extension/inference/${API}.rs + sed -i 's/pub use kube::CustomResource;/pub use kube_derive::CustomResource;/g' $APIS_DIR/experimental/extension/inference/${API}.rs + echo "pub mod ${API};" >> $APIS_DIR/experimental/extension/inference/mod.rs +done + + +export RUST_LOG=info + +mkdir -p extension/inference/ + +echo " **** Standard APIs Start **** " +echo " **** Starting Type Reducer - Collapsing Duplicative Types **** " +echo " **** Type Reducer - PHASE 1 - First Pass ***** " +cargo run --manifest-path type-reducer/Cargo.toml -- --apis-dir $APIS_DIR/standard/extension/inference --out-dir $APIS_DIR/standard/extension/inference reduce --previous-pass-derived-type-names ./type-reducer/extension/inference/standard_reduced_types_pass_0.txt --current-pass-substitute-names ./type-reducer/extension/inference/standard_customized_mapped_names.txt +mv mapped_names.txt extension/inference/standard_extension_inference_mapped_names_phase_1.txt +mv mapped_types_to_names.txt extension/inference/standard_extension_inference_mapped_types_to_names_phase_1.txt + +echo " **** RENAMING PHASE ***** " +cargo run --manifest-path type-reducer/Cargo.toml -- --apis-dir $APIS_DIR/standard/extension/inference --out-dir $APIS_DIR/standard/extension/inference rename --rename-only-substitute-names ./type-reducer/extension/inference/standard_rename_only_mapped_names.txt +echo " **** Standard APIs End **** " + + +echo " **** Experimental APIs Start **** " +echo " **** Starting Type Reducer - Collapsing Duplicative Types **** " +echo " **** Type Reducer - PHASE 1 - First Pass ***** " +cargo run --manifest-path type-reducer/Cargo.toml -- --apis-dir $APIS_DIR/experimental/extension/inference --out-dir $APIS_DIR/experimental/extension/inference reduce --previous-pass-derived-type-names ./type-reducer/extension/inference/experimental_reduced_types_pass_0.txt --current-pass-substitute-names ./type-reducer/extension/inference/experimental_customized_mapped_names.txt +mv mapped_names.txt extension/inference/experimental_extension_inference_mapped_names_phase_1.txt +mv mapped_types_to_names.txt extension/inference/experimental_extension_inference_mapped_types_to_names_phase_1.txt + +echo " **** RENAMING PHASE ***** " +cargo run --manifest-path type-reducer/Cargo.toml -- --apis-dir $APIS_DIR/experimental/extension/inference --out-dir $APIS_DIR/experimental/extension/inference rename --rename-only-substitute-names ./type-reducer/extension/inference/experimental_rename_only_mapped_names.txt +echo " **** Experimental APIs End **** " + + +cargo fmt +echo "Inference Extension API Generation complete" + +echo "Inference Extension API Cleaning up temporary files" +set -x +rm -rf extension/inference/ +set +x +echo "Inference Extension API Cleanup complete" \ No newline at end of file diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 84406bb..efd3a12 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -7,7 +7,10 @@ fn main() { match task.as_deref() { Some("gen_enum_defaults") => gen_enum_defaults().unwrap(), - Some("gen_condition_constants") => gen_condition_constants().unwrap(), + Some("gen_condition_constants") => { + let extension = env::args().nth(2); + gen_condition_constants(extension).unwrap() + } _ => print_help(), } } @@ -24,25 +27,37 @@ gen_constants generates constants used for Conditions type DynError = Box; -fn gen_condition_constants() -> Result<(), DynError> { - let gateway_class_condition_types = env::var("GATEWAY_CLASS_CONDITION_CONSTANTS")?; - let gateway_class_reason_types = env::var("GATEWAY_CLASS_REASON_CONSTANTS")?; - let gateway_condition_types = env::var("GATEWAY_CONDITION_CONSTANTS")?; - let gateway_reason_types = env::var("GATEWAY_REASON_CONSTANTS")?; - let listener_condition_types = env::var("LISTENER_CONDITION_CONSTANTS")?; - let listener_reason_types = env::var("LISTENER_REASON_CONSTANTS")?; - let route_condition_types = env::var("ROUTE_CONDITION_CONSTANTS")?; - let route_reason_types = env::var("ROUTE_REASON_CONSTANTS")?; - +fn gen_condition_constants(extension: Option) -> Result<(), DynError> { let mut scope = Scope::new(); - gen_const_enums(&mut scope, gateway_class_condition_types); - gen_const_enums(&mut scope, gateway_class_reason_types); - gen_const_enums(&mut scope, gateway_condition_types); - gen_const_enums(&mut scope, gateway_reason_types); - gen_const_enums(&mut scope, listener_condition_types); - gen_const_enums(&mut scope, listener_reason_types); - gen_const_enums(&mut scope, route_condition_types); - gen_const_enums(&mut scope, route_reason_types); + match extension { + None => { + let gateway_class_condition_types = env::var("GATEWAY_CLASS_CONDITION_CONSTANTS")?; + let gateway_class_reason_types = env::var("GATEWAY_CLASS_REASON_CONSTANTS")?; + let gateway_condition_types = env::var("GATEWAY_CONDITION_CONSTANTS")?; + let gateway_reason_types = env::var("GATEWAY_REASON_CONSTANTS")?; + let listener_condition_types = env::var("LISTENER_CONDITION_CONSTANTS")?; + let listener_reason_types = env::var("LISTENER_REASON_CONSTANTS")?; + let route_condition_types = env::var("ROUTE_CONDITION_CONSTANTS")?; + let route_reason_types = env::var("ROUTE_REASON_CONSTANTS")?; + + gen_const_enums(&mut scope, gateway_class_condition_types); + gen_const_enums(&mut scope, gateway_class_reason_types); + gen_const_enums(&mut scope, gateway_condition_types); + gen_const_enums(&mut scope, gateway_reason_types); + gen_const_enums(&mut scope, listener_condition_types); + gen_const_enums(&mut scope, listener_reason_types); + gen_const_enums(&mut scope, route_condition_types); + gen_const_enums(&mut scope, route_reason_types); + } + Some(ext) if ext == "inference" => { + let inference_extension_failure_types = + env::var("EXT_INFERENCE_FAILURE_MODE_CONSTANTS")?; + + gen_const_enums(&mut scope, inference_extension_failure_types); + } + _ => println!("Not Supported Extension!"), + } + println!("{}", gen_generated_file_warning()); println!("{}", scope.to_string()); Ok(()) @@ -81,9 +96,9 @@ fn gen_display_impl(scope: &mut Scope, ty: &str) { } fn gen_enum_defaults() -> Result<(), DynError> { - // GATEWAY_API_ENUMS provides the enum names along with their default variant to be used in the - // generated Default impl. For eg: GATEWAY_API_ENUMS=enum1=default1,enum2=default2. - let gw_api_enums = env::var("GATEWAY_API_ENUMS")?; + // API_ENUMS provides the enum names along with their default variant to be used in the + // generated Default impl. For eg: API_ENUMS=enum1=default1,enum2=default2. + let gw_api_enums = env::var("API_ENUMS")?; let enums_with_defaults = get_enums_with_defaults_map(gw_api_enums); let mut scope = Scope::new();