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

feat: refactor the opsDefinition to support task orchestration. #6735

Merged
merged 4 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
374 changes: 277 additions & 97 deletions apis/apps/v1alpha1/opsdefinition_types.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apis/apps/v1alpha1/opsrequest_conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func NewValidateFailedCondition(reason, message string) *metav1.Condition {

// NewFailedCondition creates a condition that the OpsRequest processing failed
func NewFailedCondition(ops *OpsRequest, err error) *metav1.Condition {
msg := fmt.Sprintf("Failed to process OpsRequest: %s in cluster: %s", ops.Name, ops.Spec.ClusterRef)
msg := fmt.Sprintf("Failed to process OpsRequest: %s in cluster: %s, more detailed informations in status.components", ops.Name, ops.Spec.ClusterRef)
if err != nil {
msg = err.Error()
}
Expand Down
107 changes: 97 additions & 10 deletions apis/apps/v1alpha1/opsrequest_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
)

// TODO: @wangyelei could refactor to ops group
Expand Down Expand Up @@ -301,20 +302,55 @@ type ConfigurationItem struct {
}

type CustomOpsSpec struct {
// Refers to the name of the cluster component.
// +kubebuilder:validation:Required
ComponentName string `json:"componentName"`

// Is a reference to an OpsDefinition.
// +kubebuilder:validation:Required
OpsDefinitionRef string `json:"opsDefinitionRef"`

// Represents the input for this operation as declared in the opsDefinition.spec.parametersSchema.
// It will create corresponding jobs for each array element.
// If the param type is an array, the format must be "v1,v2,v3".
// +kubebuilder:validation:MaxItem=10
ServiceAccountName *string `json:"serviceAccountName,omitempty"`

// Defines the execution concurrency. By default, all incoming Components will be executed simultaneously.
// The value can be an absolute number (e.g., 5) or a percentage of desired components (e.g., 10%).
// The absolute number is calculated from the percentage by rounding up.
// For instance, if the percentage value is 10% and the components length is 1,
// the calculated number will be rounded up to 1.
// +optional
Params []map[string]string `json:"params,omitempty"`
Parallelism intstr.IntOrString `json:"parallelism,omitempty"`

// Defines which components need to perform the actions defined by this OpsDefinition.
// At least one component is required. The components are identified by their name and can be merged or retained.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
// +patchMergeKey=name
// +patchStrategy=merge,retainKeys
// +listType=map
// +listMapKey=name
CustomOpsComponents []CustomOpsComponent `json:"components" patchStrategy:"merge,retainKeys" patchMergeKey:"name"`
}

type CustomOpsComponent struct {
// Specifies the unique identifier of the cluster component
// +kubebuilder:validation:Required
ComponentName string `json:"name"`

// Represents the parameters for this operation as declared in the opsDefinition.spec.parametersSchema.
// +patchMergeKey=name
// +patchStrategy=merge,retainKeys
// +listType=map
// +listMapKey=name
// +optional
Parameters []Parameter `json:"parameters,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"`
}

type Parameter struct {
// Specifies the identifier of the parameter as defined in the OpsDefinition.
// +kubebuilder:validation:Required
Name string `json:"name"`

// Holds the data associated with the parameter.
// If the parameter type is an array, the format should be "v1,v2,v3".
// +kubebuilder:validation:Required
Value string `json:"value"`
}

type ParameterPair struct {
Expand Down Expand Up @@ -596,6 +632,9 @@ type OpsRequestStatus struct {
// +optional
Components map[string]OpsRequestComponentStatus `json:"components,omitempty"`

// A collection of additional key-value pairs that provide supplementary information for the opsRequest.
Extras []map[string]string `json:"extras,omitempty"`

// Indicates the time when the OpsRequest started processing.
// +optional
StartTimestamp metav1.Time `json:"startTimestamp,omitempty"`
Expand Down Expand Up @@ -626,15 +665,27 @@ type OpsRequestStatus struct {
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// +kubebuilder:validation:XValidation:rule="has(self.objectKey) || has(self.actionName)", message="either objectKey and actionName."

type ProgressStatusDetail struct {
// Specifies the group to which the current object belongs.
// If the objects of a component belong to the same group, they can be ignored.
// +optional
Group string `json:"group,omitempty"`

// Represents the unique key of the object.
// +kubebuilder:validation:Required
ObjectKey string `json:"objectKey"`
// either objectKey or actionName.
// +optional
ObjectKey string `json:"objectKey,omitempty"`

// Refer to the action name of the OpsDefinition.spec.actions[*].name.
// either objectKey or actionName.
// +optional
ActionName string `json:"actionName,omitempty"`

// Records the tasks associated with an action. such as Jobs/Pods that executes action.
// +optional
ActionTasks []ActionTask `json:"actionTasks,omitempty"`

// Indicates the state of processing the object.
// +kubebuilder:validation:Required
Expand All @@ -653,6 +704,28 @@ type ProgressStatusDetail struct {
EndTime metav1.Time `json:"endTime,omitempty"`
}

type ActionTask struct {
// Specifies the name of the task workload.
// +kubebuilder:validation:Required
ObjectKey string `json:"objectKey"`

// Defines the namespace where the task workload is deployed.
// +kubebuilder:validation:Required
Namespace string `json:"namespace"`

// Indicates the current status of the task.
// +kubebuilder:validation:Required
Status ActionTaskStatus `json:"status"`

// The name of the target pod for the task.
// +optional
TargetPodName string `json:"targetPodName,omitempty"`

// The number of retry attempts for this task.
// +optional
Retries int32 `json:"retries,omitempty"`
}

type LastComponentConfiguration struct {
// Represents the last replicas of the component.
// +optional
Expand Down Expand Up @@ -701,6 +774,10 @@ type OpsRequestComponentStatus struct {
// +optional
LastFailedTime metav1.Time `json:"lastFailedTime,omitempty"`

// Specifies the outcome of the preConditions check for the opsRequest. This result is crucial for determining the next steps in the operation.
// +optional
PreCheckResult *PreCheckResult `json:"preCheck,omitempty"`

// Describes the progress details of the component for this operation.
// +optional
ProgressDetails []ProgressStatusDetail `json:"progressDetails,omitempty"`
Expand All @@ -720,6 +797,16 @@ type OpsRequestComponentStatus struct {
Message string `json:"message,omitempty" protobuf:"bytes,6,opt,name=message"`
}

type PreCheckResult struct {
// Indicates whether the preCheck operation was successful or not.
// +kubebuilder:validation:Required
Pass bool `json:"pass"`

// Provides additional details about the preCheck operation in a human-readable format.
// +optional
Message string `json:"message,omitempty"`
}

type ReconfiguringStatus struct {
// Describes the reconfiguring detail status.
// +optional
Expand Down
42 changes: 37 additions & 5 deletions apis/apps/v1alpha1/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,35 @@ const (
OpsFailedPhase OpsPhase = "Failed"
)

// PodSelectionStrategy pod selection strategy.
// PodSelectionPolicy pod selection strategy.
// +enum
// +kubebuilder:validation:Enum={Available,PreferredAvailable}
type PodSelectionStrategy string
// +kubebuilder:validation:Enum={All,Any}
type PodSelectionPolicy string

const (
Available PodSelectionStrategy = "Available"
PreferredAvailable PodSelectionStrategy = "PreferredAvailable"
All PodSelectionPolicy = "All"
Any PodSelectionPolicy = "Any"
)

// PodAvailabilityPolicy pod availability strategy.
// +enum
// +kubebuilder:validation:Enum={Available,PreferredAvailable,None}
type PodAvailabilityPolicy string

const (
AvailablePolicy PodAvailabilityPolicy = "Available"
UnAvailablePolicy PodAvailabilityPolicy = "UnAvailable"
NoneAvailabilityPolicy PodAvailabilityPolicy = "None"
)

// OpsWorkloadType policy after action failure.
// +enum
// +kubebuilder:validation:Enum={Job,Pod}
type OpsWorkloadType string

const (
PodWorkload OpsWorkloadType = "Pod"
JobWorkload OpsWorkloadType = "Job"
)

// OpsType defines operation types.
Expand Down Expand Up @@ -484,6 +505,17 @@ const (
SucceedProgressStatus ProgressStatus = "Succeed"
)

// ActionTaskStatus defines the status of the task.
// +enum
// +kubebuilder:validation:Enum={Processing,Failed,Succeed}
type ActionTaskStatus string

const (
ProcessingActionTaskStatus ActionTaskStatus = "Processing"
FailedActionTaskStatus ActionTaskStatus = "Failed"
SucceedActionTaskStatus ActionTaskStatus = "Succeed"
)

type OpsRequestBehaviour struct {
FromClusterPhases []ClusterPhase
ToClusterPhase ClusterPhase
Expand Down
Loading
Loading