Skip to content

Commit

Permalink
feature: support ops definition
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyelei committed Nov 27, 2023
1 parent 492cc65 commit b377342
Show file tree
Hide file tree
Showing 52 changed files with 18,655 additions and 91 deletions.
9 changes: 9 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,13 @@ resources:
defaulting: true
validation: true
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: kubeblocks.io
group: apps
kind: OpsDefinition
path: github.com/apecloud/kubeblocks/apis/apps/v1alpha1
version: v1alpha1
version: "3"
6 changes: 6 additions & 0 deletions apis/apps/v1alpha1/componentdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ type SystemAccount struct {

// SecretRef specifies the secret from which data will be copied to create the new account.
// Cannot be updated.
// And will replace the built-in objects in the secret:
// - `$(RANDOM_PASSWD)` - random 8 characters.
// - `$(UUID)` - generate a random UUID v4 string.
// - `$(UUID_B64)` - generate a random UUID v4 BASE64 encoded string.
// - `$(UUID_STR_B64)` - generate a random UUID v4 string then BASE64 encoded.
// - `$(UUID_HEX)` - generate a random UUID v4 HEX representation.
// +optional
SecretRef *ProvisionSecretRef `json:"secretRef,omitempty"`
}
Expand Down
175 changes: 175 additions & 0 deletions apis/apps/v1alpha1/opsdefinition_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
Copyright (C) 2022-2023 ApeCloud Co., Ltd
This file is part of KubeBlocks project
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package v1alpha1

import (
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// OpsDefinitionSpec defines the desired state of OpsDefinition
type OpsDefinitionSpec struct {
// triggerPhaseChange indicates whether the operation will trigger a state change of the component.
// if true, will be queued for execution.
// +optional
TriggerPhaseChange bool `json:"triggerPhaseChange,omitempty"`

// componentDefinitionRefs indicates which types of componentDefinitions are supported by the operation.
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
// +patchMergeKey=serviceKind
// +patchStrategy=merge,retainKeys
// +listType=map
// +listMapKey=serviceKind
ComponentDefinitionRefs []ComponentDefinitionRef `json:"componentDefinitionRefs" patchStrategy:"merge,retainKeys" patchMergeKey:"serviceKind"`

// parametersSchema describes the schema used for validation, pruning, and defaulting.
// +optional
ParametersSchema *ParametersSchema `json:"parametersSchema,omitempty"`

// jobSpec describes the job spec for the operation.
// +kubebuilder:validation:Required
JobSpec batchv1.JobSpec `json:"jobSpec"`

// pre-check if it meets the requirements to run the job for the operation.
// +optional
PreChecks []PreCheck `json:"preChecks,omitempty"`
}

type ComponentDefinitionRef struct {

// ServiceKind defines what kind of well-known service that the component provides (e.g., MySQL, Redis, ETCD, case insensitive).
// reference componentDefinition.spec.
// +kubebuilder:validation:MaxLength=32
// +kubebuilder:validation:Required
ServiceKind string `json:"serviceKind"`

// the data of the specified connection credential will be injected into env of the job.
// if not set, use the first connection credential by default.
// +optional
ConnectionCredentialName string `json:"connectionCredentialName"`

// map the name and ports to KB_COMP_SVC_NAME and KB_COMP_SVC_PORT_<port> in env of the job.
// +optional
ServiceName string `json:"serviceName,omitempty"`
}

type ParametersSchema struct {
// openAPIV3SchemaProperties is the OpenAPI v3 schema to use for parameter schema.
// +kubebuilder:validation:Schemaless
// +kubebuilder:validation:Type=object
// +kubebuilder:pruning:PreserveUnknownFields
// +k8s:conversion-gen=false
// +optional
OpenAPIV3Schema *apiextensions.JSONSchemaProps `json:"openAPIV3Schema,omitempty"`
}

// PreCheck
// +kubebuilder:validation:XValidation:rule="has(self.expression) || has(self.exec)", message="at least one exists for expression and exec."
type PreCheck struct {

// expression declares how the operation can be executed.
Expression *Expression `json:"expression,omitempty"`

// a job will be run to execute pre-check.
// +optional
Exec *PreCheckExec `json:"exec,omitempty"`
}

type Expression struct {
// validation rule declares how the operation can be executed using go template expression.
// it should return "true" or "false", built-in objects:
// - "params" are input parameters.
// - "cluster" is referenced cluster object.
// - "component" is referenced the component Object.
// +kubebuilder:validation:Required
Rule string `json:"rule"`

// report the message if the rule is not matched.
// +kubebuilder:validation:Required
Message string `json:"message"`
}

type PreCheckExec struct {
// image name.
// +kubebuilder:validation:Required
Image string `json:"image"`

// container env.
// +optional
Env []corev1.EnvVar `json:"env,omitempty"`

// container commands.
// +optional
Command []string `json:"command,omitempty"`

// container args.
// +optional
Args []string `json:"args,omitempty"`
}

// OpsDefinitionStatus defines the observed state of OpsDefinition
type OpsDefinitionStatus struct {
// ObservedGeneration is the most recent generation observed for this OpsDefinition.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// Phase valid values are ``, `Available`, 'Unavailable`.
// Available is OpsDefinition become available, and can be used for co-related objects.
// +optional
Phase Phase `json:"phase,omitempty"`

// Extra message for current phase.
// +optional
Message string `json:"message,omitempty"`
}

// +genclient
// +genclient:nonNamespaced
// +k8s:openapi-gen=true
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:categories={kubeblocks,all},scope=Cluster,shortName=od
// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.phase",description="Operation status phase."
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"

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

Spec OpsDefinitionSpec `json:"spec,omitempty"`
Status OpsDefinitionStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

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

func init() {
SchemeBuilder.Register(&OpsDefinition{}, &OpsDefinitionList{})
}
18 changes: 17 additions & 1 deletion apis/apps/v1alpha1/opsrequest_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
// OpsRequestSpec defines the desired state of OpsRequest
// +kubebuilder:validation:XValidation:rule="has(self.cancel) && self.cancel ? (self.type in ['VerticalScaling', 'HorizontalScaling']) : true",message="forbidden to cancel the opsRequest which type not in ['VerticalScaling','HorizontalScaling']"
type OpsRequestSpec struct {
// clusterRef references clusterDefinition.
// clusterRef references cluster object.
// +kubebuilder:validation:Required
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="forbidden to update spec.clusterRef"
ClusterRef string `json:"clusterRef"`
Expand Down Expand Up @@ -139,6 +139,8 @@ type OpsRequestSpec struct {
// restoreSpec defines how to restore the cluster.
// +optional
RestoreSpec *RestoreSpec `json:"restoreSpec,omitempty"`

CustomSpec *CustomOpsSpec `json:"customSpec,omitempty"`
}

// ComponentOps defines the common variables of component scope operations.
Expand Down Expand Up @@ -266,6 +268,20 @@ type ConfigurationItem struct {
Keys []ParameterConfig `json:"keys" patchStrategy:"merge,retainKeys" patchMergeKey:"key"`
}

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

// +kubebuilder:validation:Required
// reference a opsDefinition
OpsDefinitionRef string `json:"opsDefinitionRef"`

// the input for this operation declared in the opsDefinition.spec.parametersSchema.
// +optional
Params map[string]string `json:"params,omitempty"`
}

type ParameterPair struct {
// key is name of the parameter to be updated.
// +kubebuilder:validation:Required
Expand Down
3 changes: 2 additions & 1 deletion apis/apps/v1alpha1/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ const (

// OpsType defines operation types.
// +enum
// +kubebuilder:validation:Enum={Upgrade,VerticalScaling,VolumeExpansion,HorizontalScaling,Restart,Reconfiguring,Start,Stop,Expose,Switchover,DataScript,Backup,Restore}
// +kubebuilder:validation:Enum={Upgrade,VerticalScaling,VolumeExpansion,HorizontalScaling,Restart,Reconfiguring,Start,Stop,Expose,Switchover,DataScript,Backup,Restore,Custom}
type OpsType string

const (
Expand All @@ -234,6 +234,7 @@ const (
DataScriptType OpsType = "DataScript" // DataScriptType the data script operation will execute the data script against the cluster.
BackupType OpsType = "Backup"
RestoreType OpsType = "Restore"
CustomType OpsType = "Custom" // use opsDefinition
)

// ComponentResourceKey defines the resource key of component, such as pod/pvc.
Expand Down
Loading

0 comments on commit b377342

Please sign in to comment.