Skip to content

Commit

Permalink
feat: opsDef and bpt support cmpd name prefix and regex matching
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyelei committed Sep 20, 2024
1 parent 0a4aaac commit fa21bee
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 48 deletions.
28 changes: 23 additions & 5 deletions apis/apps/v1alpha1/backuppolicytemplate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,14 @@ type BackupPolicy struct {
// +optional
ComponentDefRef string `json:"componentDefRef,omitempty"`

// Specifies a list of names of ComponentDefinitions that the specified ClusterDefinition references.
// They should be different versions of definitions of the same component,
// thus allowing them to share a single BackupPolicy.
// Each name must adhere to the IANA Service Naming rule.
// Specifies the name of the ComponentDefinition.
// Each name in the list can represent an exact name, a name prefix, or a regular expression pattern.
//
// For example:
//
// - "mysql-8.0.30-v1alpha1": Matches the exact name "mysql-8.0.30-v1alpha1"
// - "mysql-8.0.30": Matches all names starting with "mysql-8.0.30"
// - "^mysql-8.0.\d{1,2}$": Matches all names starting with "mysql-8.0." followed by one or two digits.
//
// +optional
ComponentDefs []string `json:"componentDefs,omitempty"`
Expand Down Expand Up @@ -143,18 +147,32 @@ type ValueFrom struct {
ClusterVersionRef []ValueMapping `json:"clusterVersionRef,omitempty"`

// Determine the appropriate version of the backup tool image from ComponentDefinition.
// Each name in the list can represent an exact name, a name prefix, or a regular expression pattern.
//
// For example:
//
// - "mysql-8.0.30-v1alpha1": Matches the exact name "mysql-8.0.30-v1alpha1"
// - "mysql-8.0.30": Matches all names starting with "mysql-8.0.30"
// - "^mysql-8.0.\d{1,2}$": Matches all names starting with "mysql-8.0." followed by one or two digits.
//
// +optional
ComponentDef []ValueMapping `json:"componentDef,omitempty"`

// Determine the appropriate version of the backup tool image from ServiceVersion.
// Each service version in the list can represent an exact version, a version prefix, or a regular expression pattern.
//
// For example:
//
// - "8.0.33": Matches the exact version "8.0.33"
// - "8.0": Matches all versions starting with "8.0"
// - "^8.0.\d{1,2}$": Matches all versions starting with "8.0." followed by one or two digits.
//
// +optional
ServiceVersion []ValueMapping `json:"serviceVersion,omitempty"`
}

type ValueMapping struct {
// Represents an array of names of ClusterVersion or ComponentDefinition that can be mapped to
// Represents an array of names of ClusterVersion or ComponentDefinition or ServiceVersion that can be mapped to
// the appropriate version of the backup tool image.
//
// This mapping allows different versions of component images to correspond to specific versions of backup tool images.
Expand Down
8 changes: 8 additions & 0 deletions apis/apps/v1alpha1/opsdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ type PodSelector struct {

type ComponentInfo struct {
// Specifies the name of the ComponentDefinition.
// The name can represent an exact name, a name prefix, or a regular expression pattern.
//
// For example:
//
// - "mysql-8.0.30-v1alpha1": Matches the exact name "mysql-8.0.30-v1alpha1"
// - "mysql-8.0.30": Matches all names starting with "mysql-8.0.30"
// - "^mysql-8.0.\d{1,2}$": Matches all names starting with "mysql-8.0." followed by one or two digits.
//
// +kubebuilder:validation:MaxLength=32
// +kubebuilder:validation:Required
ComponentDefinitionName string `json:"componentDefinitionName"`
Expand Down
2 changes: 1 addition & 1 deletion apis/apps/v1alpha1/opsrequest_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ type UpgradeComponent struct {
// Specifies the name of the Component.
ComponentOps `json:",inline"`

// Specifies the name of the ComponentDefinition.
// Specifies the name of the ComponentDefinition, only exact matches are supported.
// +kubebuilder:validation:MaxLength=64
// +optional
ComponentDefinitionName *string `json:"componentDefinitionName,omitempty"`
Expand Down
46 changes: 35 additions & 11 deletions config/crd/bases/apps.kubeblocks.io_backuppolicytemplates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ spec:
type: string
names:
description: |-
Represents an array of names of ClusterVersion or ComponentDefinition that can be mapped to
Represents an array of names of ClusterVersion or ComponentDefinition or ServiceVersion that can be mapped to
the appropriate version of the backup tool image.
Expand All @@ -245,8 +245,17 @@ spec:
type: object
type: array
componentDef:
description: Determine the appropriate version
of the backup tool image from ComponentDefinition.
description: |-
Determine the appropriate version of the backup tool image from ComponentDefinition.
Each name in the list can represent an exact name, a name prefix, or a regular expression pattern.
For example:
- "mysql-8.0.30-v1alpha1": Matches the exact name "mysql-8.0.30-v1alpha1"
- "mysql-8.0.30": Matches all names starting with "mysql-8.0.30"
- "^mysql-8.0.\d{1,2}$": Matches all names starting with "mysql-8.0." followed by one or two digits.
items:
properties:
mappingValue:
Expand All @@ -255,7 +264,7 @@ spec:
type: string
names:
description: |-
Represents an array of names of ClusterVersion or ComponentDefinition that can be mapped to
Represents an array of names of ClusterVersion or ComponentDefinition or ServiceVersion that can be mapped to
the appropriate version of the backup tool image.
Expand All @@ -269,8 +278,17 @@ spec:
type: object
type: array
serviceVersion:
description: Determine the appropriate version
of the backup tool image from ServiceVersion.
description: |-
Determine the appropriate version of the backup tool image from ServiceVersion.
Each service version in the list can represent an exact version, a version prefix, or a regular expression pattern.
For example:
- "8.0.33": Matches the exact version "8.0.33"
- "8.0": Matches all versions starting with "8.0"
- "^8.0.\d{1,2}$": Matches all versions starting with "8.0." followed by one or two digits.
items:
properties:
mappingValue:
Expand All @@ -279,7 +297,7 @@ spec:
type: string
names:
description: |-
Represents an array of names of ClusterVersion or ComponentDefinition that can be mapped to
Represents an array of names of ClusterVersion or ComponentDefinition or ServiceVersion that can be mapped to
the appropriate version of the backup tool image.
Expand Down Expand Up @@ -960,10 +978,16 @@ spec:
type: string
componentDefs:
description: |-
Specifies a list of names of ComponentDefinitions that the specified ClusterDefinition references.
They should be different versions of definitions of the same component,
thus allowing them to share a single BackupPolicy.
Each name must adhere to the IANA Service Naming rule.
Specifies the name of the ComponentDefinition.
Each name in the list can represent an exact name, a name prefix, or a regular expression pattern.
For example:
- "mysql-8.0.30-v1alpha1": Matches the exact name "mysql-8.0.30-v1alpha1"
- "mysql-8.0.30": Matches all names starting with "mysql-8.0.30"
- "^mysql-8.0.\d{1,2}$": Matches all names starting with "mysql-8.0." followed by one or two digits.
items:
type: string
type: array
Expand Down
12 changes: 11 additions & 1 deletion config/crd/bases/apps.kubeblocks.io_opsdefinitions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7627,7 +7627,17 @@ spec:
`KB_ACCOUNT_USERNAME` and `KB_ACCOUNT_PASSWORD`.
type: string
componentDefinitionName:
description: Specifies the name of the ComponentDefinition.
description: |-
Specifies the name of the ComponentDefinition.
The name can represent an exact name, a name prefix, or a regular expression pattern.


For example:


- "mysql-8.0.30-v1alpha1": Matches the exact name "mysql-8.0.30-v1alpha1"
- "mysql-8.0.30": Matches all names starting with "mysql-8.0.30"
- "^mysql-8.0.\d{1,2}$": Matches all names starting with "mysql-8.0." followed by one or two digits.
maxLength: 32
type: string
serviceName:
Expand Down
3 changes: 2 additions & 1 deletion config/crd/bases/apps.kubeblocks.io_opsrequests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4832,7 +4832,8 @@ spec:
items:
properties:
componentDefinitionName:
description: Specifies the name of the ComponentDefinition.
description: Specifies the name of the ComponentDefinition,
only exact matches are supported.
maxLength: 64
type: string
componentName:
Expand Down
21 changes: 19 additions & 2 deletions controllers/apps/backuppolicytemplate_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (

appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1"
"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/apecloud/kubeblocks/pkg/controller/component"
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
)

Expand Down Expand Up @@ -58,10 +59,16 @@ func (r *BackupPolicyTemplateReconciler) Reconcile(ctx context.Context, req reco
if backupPolicyTemplate.Spec.ClusterDefRef != "" {
backupPolicyTemplate.Labels[constant.ClusterDefLabelKey] = backupPolicyTemplate.Spec.ClusterDefRef
}

compDefList := &appsv1alpha1.ComponentDefinitionList{}
if err := r.Client.List(ctx, compDefList); err != nil {
return intctrlutil.CheckedRequeueWithError(err, reqCtx.Log, "")
}
for _, backupPolicy := range backupPolicyTemplate.Spec.BackupPolicies {
for _, compDef := range backupPolicy.ComponentDefs {
backupPolicyTemplate.Labels[compDef] = compDef
matchedCompDefNames := r.getMatchedComponentDefs(compDefList, compDef)
for _, compDefName := range matchedCompDefNames {
backupPolicyTemplate.Labels[compDefName] = compDefName
}
}
}

Expand All @@ -72,6 +79,16 @@ func (r *BackupPolicyTemplateReconciler) Reconcile(ctx context.Context, req reco
return intctrlutil.Reconciled()
}

func (r *BackupPolicyTemplateReconciler) getMatchedComponentDefs(compDefList *appsv1alpha1.ComponentDefinitionList, compDef string) []string {
var compDefNames []string
for i, item := range compDefList.Items {
if component.CompDefMatched(item.Name, compDef) {
compDefNames = append(compDefNames, compDefList.Items[i].Name)
}
}
return compDefNames
}

// SetupWithManager sets up the controller with the Manager.
func (r *BackupPolicyTemplateReconciler) SetupWithManager(mgr ctrl.Manager) error {
return intctrlutil.NewNamespacedControllerManagedBy(mgr).
Expand Down
2 changes: 1 addition & 1 deletion controllers/apps/operations/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func initOpsDefAndValidate(reqCtx intctrlutil.RequestCtx,
if len(opsDef.Spec.ComponentInfos) > 0 {
var componentDefMatched bool
for _, c := range opsDef.Spec.ComponentInfos {
if c.ComponentDefinitionName == compDef.Name {
if component.CompDefMatched(compDef.Name, c.ComponentDefinitionName) {
componentDefMatched = true
break
}
Expand Down
20 changes: 16 additions & 4 deletions controllers/apps/transformer_cluster_backup_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
workloads "github.com/apecloud/kubeblocks/apis/workloads/v1alpha1"
"github.com/apecloud/kubeblocks/pkg/common"
"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/apecloud/kubeblocks/pkg/controller/component"
"github.com/apecloud/kubeblocks/pkg/controller/graph"
"github.com/apecloud/kubeblocks/pkg/controller/model"
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
Expand Down Expand Up @@ -458,29 +459,41 @@ func (r *clusterBackupPolicyTransformer) doEnvMapping(comp *appsv1alpha1.Cluster
Name: v.Key,
Value: cv.MappingValue,
})
break
}
for _, cm := range v.ValueFrom.ComponentDef {
if !slices.Contains(cm.Names, comp.ComponentDef) {
if !r.matchMappingName(cm.Names, comp.ComponentDef) {
continue
}
env = append(env, corev1.EnvVar{
Name: v.Key,
Value: cm.MappingValue,
})
break
}
for _, sv := range v.ValueFrom.ServiceVersion {
if !slices.Contains(sv.Names, comp.ServiceVersion) {
if !r.matchMappingName(sv.Names, comp.ServiceVersion) {
continue
}
env = append(env, corev1.EnvVar{
Name: v.Key,
Value: sv.MappingValue,
})
break
}
}
return env
}

func (r *clusterBackupPolicyTransformer) matchMappingName(names []string, target string) bool {
for _, name := range names {
if component.CompDefMatched(target, name) {
return true
}
}
return false
}

func (r *clusterBackupPolicyTransformer) syncBackupPolicyTargetSpec(backupPolicy *dpv1alpha1.BackupPolicy, comp componentItem) {
if comp.isSharding {
backupPolicy.Spec.Targets = r.buildBackupTargets(backupPolicy.Spec.Targets, comp)
Expand Down Expand Up @@ -679,9 +692,8 @@ func (r *clusterBackupPolicyTransformer) mergeClusterBackup(
// getClusterComponentSpec returns the component which matches the componentDef or componentDefRef.
func (r *clusterBackupPolicyTransformer) getClusterComponentItems() []componentItem {
matchedCompDef := func(compSpec appsv1alpha1.ClusterComponentSpec) bool {
// TODO: support to create bp when using cluster topology and componentDef is empty
return (compSpec.ComponentDefRef != "" && compSpec.ComponentDefRef == r.backupPolicy.ComponentDefRef) ||
(compSpec.ComponentDef != "" && slices.Contains(r.backupPolicy.ComponentDefs, compSpec.ComponentDef))
(compSpec.ComponentDef != "" && r.matchMappingName(r.backupPolicy.ComponentDefs, compSpec.ComponentDef))
}
var compSpecItems []componentItem
for i, v := range r.clusterTransformContext.Cluster.Spec.ComponentSpecs {
Expand Down
Loading

0 comments on commit fa21bee

Please sign in to comment.