Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(crds): Use built-in OpenAPI validation #5129

Merged
merged 2 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 52 additions & 31 deletions operator/apis/mlops/v1alpha1/pipeline_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,77 @@ import (
"github.com/seldonio/seldon-core/apis/go/v2/mlops/scheduler"
)

//+kubebuilder:object:root=true
Copy link
Contributor Author

@jesse-c jesse-c Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explain: More conventional kubebuilder annotations to have this for both structs, and to be ordered this way. This is also the same for the new lines between fields.

//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName=mlp

// Pipeline is the Schema for the pipelines API
type Pipeline struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec PipelineSpec `json:"spec,omitempty"`
Status PipelineStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// PipelineList contains a list of Pipeline
type PipelineList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`

Items []Pipeline `json:"items"`
}

// PipelineSpec defines the desired state of Pipeline
type PipelineSpec struct {
// External inputs to this pipeline, optional
Input *PipelineInput `json:"input,omitempty"`

// The steps of this inference graph pipeline
Steps []PipelineStep `json:"steps"`

// Synchronous output from this pipeline, optional
Output *PipelineOutput `json:"output,omitempty"`
}

// +kubebuilder:validation:Enum=inner;outer;any
type JoinType string

const (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explain: It's not ideal that it's repeated here, but this approach seems common [1].

[1] https://github.com/search?q=%2Bkubebuilder%3Avalidation%3AEnum&type=code — e.g. Grafana, Cilium, etc.

// data must be available from all inputs
JoinTypeInner JoinType = "inner"
// data will include any data from any inputs at end of window
JoinTypeOuter JoinType = "outer"
JoinTypeAny JoinType = "any"
// first data input that arrives will be forwarded
JoinTypeAny JoinType = "any"
)

type PipelineStep struct {
// Name of the step
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
ukclivecox marked this conversation as resolved.
Show resolved Hide resolved
// +kubebuilder:validation:Pattern=`^[a-z0-9][a-z0-9\-\.]+[a-z0-9]+$`
Name string `json:"name"`

// Previous step to receive data from
Inputs []string `json:"inputs,omitempty"`

// msecs to wait for messages from multiple inputs to arrive before joining the inputs
JoinWindowMs *uint32 `json:"joinWindowMs,omitempty"`

// Map of tensor name conversions to use e.g. output1 -> input1
TensorMap map[string]string `json:"tensorMap,omitempty"`

// Triggers required to activate step
Triggers []string `json:"triggers,omitempty"`
// One of inner (default), outer, or any
// inner - do an inner join: data must be available from all inputs
// outer - do an outer join: data will include any data from any inputs at end of window
// any - first data input that arrives will be forwarded

// +kubebuilder:default=inner
InputsJoinType *JoinType `json:"inputsJoinType,omitempty"`
// One of inner (default), outer, or any (see above for details)

TriggersJoinType *JoinType `json:"triggersJoinType,omitempty"`

// Batch size of request required before data will be sent to this step
Batch *PipelineBatch `json:"batch,omitempty"`
}
Expand All @@ -74,25 +109,33 @@ type PipelineBatch struct {
type PipelineInput struct {
// Previous external pipeline steps to receive data from
ExternalInputs []string `json:"externalInputs,omitempty"`

// Triggers required to activate inputs
ExternalTriggers []string `json:"externalTriggers,omitempty"`

// msecs to wait for messages from multiple inputs to arrive before joining the inputs
JoinWindowMs *uint32 `json:"joinWindowMs,omitempty"`
// One of inner (default), outer, or any (see above for details)

// +kubebuilder:default=inner
JoinType *JoinType `json:"joinType,omitempty"`
// One of inner (default), outer, or any (see above for details)

// +kubebuilder:default=inner
TriggersJoinType *JoinType `json:"triggersJoinType,omitempty"`

// Map of tensor name conversions to use e.g. output1 -> input1
TensorMap map[string]string `json:"tensorMap,omitempty"`
}

type PipelineOutput struct {
// Previous step to receive data from
Steps []string `json:"steps,omitempty"`

// msecs to wait for messages from multiple inputs to arrive before joining the inputs
JoinWindowMs uint32 `json:"joinWindowMs,omitempty"`
// One of inner (default), outer, or any (see above for details)

// +kubebuilder:default=inner
StepsJoin *JoinType `json:"stepsJoin,omitempty"`

// Map of tensor name conversions to use e.g. output1 -> input1
TensorMap map[string]string `json:"tensorMap,omitempty"`
}
Expand All @@ -102,28 +145,6 @@ type PipelineStatus struct {
duckv1.Status `json:",inline"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName=mlp

// Pipeline is the Schema for the pipelines API
type Pipeline struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec PipelineSpec `json:"spec,omitempty"`
Status PipelineStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// PipelineList contains a list of Pipeline
type PipelineList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Pipeline `json:"items"`
}

func init() {
SchemeBuilder.Register(&Pipeline{}, &PipelineList{})
}
Expand Down
40 changes: 27 additions & 13 deletions operator/config/crd/bases/mlops.seldon.io_pipelines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ spec:
type: string
type: array
joinType:
description: One of inner (default), outer, or any (see above
for details)
default: inner
enum:
- inner
- outer
- any
type: string
joinWindowMs:
description: msecs to wait for messages from multiple inputs to
Expand All @@ -67,8 +70,11 @@ spec:
-> input1
type: object
triggersJoinType:
description: One of inner (default), outer, or any (see above
for details)
default: inner
enum:
- inner
- outer
- any
type: string
type: object
output:
Expand All @@ -85,8 +91,11 @@ spec:
type: string
type: array
stepsJoin:
description: One of inner (default), outer, or any (see above
for details)
default: inner
enum:
- inner
- outer
- any
type: string
tensorMap:
additionalProperties:
Expand Down Expand Up @@ -118,11 +127,11 @@ spec:
type: string
type: array
inputsJoinType:
description: 'One of inner (default), outer, or any inner -
do an inner join: data must be available from all inputs outer
- do an outer join: data will include any data from any inputs
at end of window any - first data input that arrives will
be forwarded'
default: inner
enum:
- inner
- outer
- any
type: string
joinWindowMs:
description: msecs to wait for messages from multiple inputs
Expand All @@ -131,6 +140,9 @@ spec:
type: integer
name:
description: Name of the step
maxLength: 253
minLength: 1
pattern: ^[a-z0-9][a-z0-9\-\.]+[a-z0-9]+$
type: string
tensorMap:
additionalProperties:
Expand All @@ -144,8 +156,10 @@ spec:
type: string
type: array
triggersJoinType:
description: One of inner (default), outer, or any (see above
for details)
enum:
- inner
- outer
- any
type: string
required:
- name
Expand Down
Loading