mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-14 18:10:21 +00:00
Feat: optimize the definition controllers (#4751)
* Feat: optimize the definition controllers Signed-off-by: barnettZQG <barnett.zqg@gmail.com> * Fix: generate the different label key Signed-off-by: barnettZQG <barnett.zqg@gmail.com> * Fix: add the comment Signed-off-by: barnettZQG <barnett.zqg@gmail.com> * Fix: update the comment Signed-off-by: barnettZQG <barnett.zqg@gmail.com> Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
This commit is contained in:
@@ -138,7 +138,8 @@ type TraitDefinitionSpec struct {
|
||||
// +optional
|
||||
ConflictsWith []string `json:"conflictsWith,omitempty"`
|
||||
|
||||
// Schematic defines the data format and template of the encapsulation of the trait
|
||||
// Schematic defines the data format and template of the encapsulation of the trait.
|
||||
// Only CUE and Kube schematic are supported for now.
|
||||
// +optional
|
||||
Schematic *common.Schematic `json:"schematic,omitempty"`
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ type PolicyDefinitionSpec struct {
|
||||
// Reference to the CustomResourceDefinition that defines this trait kind.
|
||||
Reference common.DefinitionReference `json:"definitionRef,omitempty"`
|
||||
|
||||
// Schematic defines the data format and template of the encapsulation of the policy definition
|
||||
// Schematic defines the data format and template of the encapsulation of the policy definition.
|
||||
// Only CUE schematic is supported for now.
|
||||
// +optional
|
||||
Schematic *common.Schematic `json:"schematic,omitempty"`
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ type WorkflowStepDefinitionSpec struct {
|
||||
// Reference to the CustomResourceDefinition that defines this trait kind.
|
||||
Reference common.DefinitionReference `json:"definitionRef,omitempty"`
|
||||
|
||||
// Schematic defines the data format and template of the encapsulation of the workflow step definition
|
||||
// Schematic defines the data format and template of the encapsulation of the workflow step definition.
|
||||
// Only CUE schematic is supported for now.
|
||||
// +optional
|
||||
Schematic *common.Schematic `json:"schematic,omitempty"`
|
||||
}
|
||||
|
||||
@@ -3305,7 +3305,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the policy definition
|
||||
of the encapsulation of the policy definition. Only CUE
|
||||
schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -3731,7 +3732,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the trait
|
||||
of the encapsulation of the trait. Only CUE and Kube schematic
|
||||
are supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -4190,7 +4192,8 @@ spec:
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the workflow step definition
|
||||
of the encapsulation of the workflow step definition.
|
||||
Only CUE schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -445,7 +445,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the policy definition
|
||||
of the encapsulation of the policy definition. Only CUE
|
||||
schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -762,7 +763,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the trait
|
||||
of the encapsulation of the trait. Only CUE and Kube schematic
|
||||
are supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -1052,7 +1054,8 @@ spec:
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the workflow step definition
|
||||
of the encapsulation of the workflow step definition. Only
|
||||
CUE schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -60,7 +60,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the policy definition
|
||||
encapsulation of the policy definition. Only CUE schematic is supported
|
||||
for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -410,7 +410,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the trait
|
||||
encapsulation of the trait. Only CUE and Kube schematic are supported
|
||||
for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -57,7 +57,8 @@ spec:
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the workflow step definition
|
||||
encapsulation of the workflow step definition. Only CUE schematic
|
||||
is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -3305,7 +3305,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the policy definition
|
||||
of the encapsulation of the policy definition. Only CUE
|
||||
schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -3731,7 +3732,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the trait
|
||||
of the encapsulation of the trait. Only CUE and Kube schematic
|
||||
are supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -4190,7 +4192,8 @@ spec:
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the workflow step definition
|
||||
of the encapsulation of the workflow step definition.
|
||||
Only CUE schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -445,7 +445,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the policy definition
|
||||
of the encapsulation of the policy definition. Only CUE
|
||||
schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -762,7 +763,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the trait
|
||||
of the encapsulation of the trait. Only CUE and Kube schematic
|
||||
are supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -1052,7 +1054,8 @@ spec:
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the workflow step definition
|
||||
of the encapsulation of the workflow step definition. Only
|
||||
CUE schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -60,7 +60,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the policy definition
|
||||
encapsulation of the policy definition. Only CUE schematic is supported
|
||||
for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -410,7 +410,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the trait
|
||||
encapsulation of the trait. Only CUE and Kube schematic are supported
|
||||
for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -57,7 +57,8 @@ spec:
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the workflow step definition
|
||||
encapsulation of the workflow step definition. Only CUE schematic
|
||||
is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -3305,7 +3305,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the policy definition
|
||||
of the encapsulation of the policy definition. Only CUE
|
||||
schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -3731,7 +3732,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the trait
|
||||
of the encapsulation of the trait. Only CUE and Kube schematic
|
||||
are supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -4190,7 +4192,8 @@ spec:
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the workflow step definition
|
||||
of the encapsulation of the workflow step definition.
|
||||
Only CUE schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -445,7 +445,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the policy definition
|
||||
of the encapsulation of the policy definition. Only CUE
|
||||
schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -762,7 +763,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the trait
|
||||
of the encapsulation of the trait. Only CUE and Kube schematic
|
||||
are supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
@@ -1052,7 +1054,8 @@ spec:
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template
|
||||
of the encapsulation of the workflow step definition
|
||||
of the encapsulation of the workflow step definition. Only
|
||||
CUE schematic is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -60,7 +60,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the policy definition
|
||||
encapsulation of the policy definition. Only CUE schematic is supported
|
||||
for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -410,7 +410,8 @@ spec:
|
||||
type: boolean
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the trait
|
||||
encapsulation of the trait. Only CUE and Kube schematic are supported
|
||||
for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -57,7 +57,8 @@ spec:
|
||||
type: object
|
||||
schematic:
|
||||
description: Schematic defines the data format and template of the
|
||||
encapsulation of the workflow step definition
|
||||
encapsulation of the workflow step definition. Only CUE schematic
|
||||
is supported for now.
|
||||
properties:
|
||||
cue:
|
||||
description: CUE defines the encapsulation in CUE format
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/klog/v2"
|
||||
@@ -36,12 +35,10 @@ import (
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
common2 "github.com/oam-dev/kubevela/pkg/controller/common"
|
||||
oamctrl "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
|
||||
coredef "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/core"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/version"
|
||||
@@ -76,59 +73,23 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
if !r.matchControllerRequirement(&componentDefinition) {
|
||||
klog.InfoS("skip componentDefinition: not match the controller requirement of componentDefinition", "componentDefinition", klog.KObj(&componentDefinition))
|
||||
if !coredef.MatchControllerRequirement(&componentDefinition, r.controllerVersion, r.ignoreDefNoCtrlReq) {
|
||||
klog.InfoS("skip definition: not match the controller requirement of definition", "componentDefinition", klog.KObj(&componentDefinition))
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// refresh package discover when componentDefinition is registered
|
||||
if componentDefinition.Spec.Workload.Type != types.AutoDetectWorkloadDefinition {
|
||||
err := utils.RefreshPackageDiscover(ctx, r.Client, r.dm, r.pd, &componentDefinition)
|
||||
if err != nil {
|
||||
klog.InfoS("Could not discover the open api of the CRD", "err", err)
|
||||
r.record.Event(&componentDefinition, event.Warning("Could not discover the open api of the CRD", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &componentDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrRefreshPackageDiscover, err)))
|
||||
}
|
||||
}
|
||||
|
||||
// generate DefinitionRevision from componentDefinition
|
||||
defRev, isNewRevision, err := coredef.GenerateDefinitionRevision(ctx, r.Client, &componentDefinition)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Could not generate DefinitionRevision", "componentDefinition", klog.KObj(&componentDefinition))
|
||||
r.record.Event(&componentDefinition, event.Warning("Could not generate DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrGenerateDefinitionRevision, componentDefinition.Name, err)))
|
||||
}
|
||||
|
||||
if isNewRevision {
|
||||
if err := r.createComponentDefRevision(ctx, &componentDefinition, defRev.DeepCopy()); err != nil {
|
||||
klog.ErrorS(err, "Could not create DefinitionRevision")
|
||||
r.record.Event(&componentDefinition, event.Warning("cannot create DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrCreateDefinitionRevision, defRev.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully created definitionRevision", "definitionRevision", klog.KObj(defRev))
|
||||
|
||||
componentDefinition.Status.LatestRevision = &common.Revision{
|
||||
Name: defRev.Name,
|
||||
Revision: defRev.Spec.Revision,
|
||||
RevisionHash: defRev.Spec.RevisionHash,
|
||||
}
|
||||
|
||||
defRev, result, err := coredef.ReconcileDefinitionRevision(ctx, r.Client, r.record, &componentDefinition, r.defRevLimit, func(revision *common.Revision) error {
|
||||
componentDefinition.Status.LatestRevision = revision
|
||||
if err := r.UpdateStatus(ctx, &componentDefinition); err != nil {
|
||||
klog.ErrorS(err, "Could not update componentDefinition Status")
|
||||
r.record.Event(&componentDefinition, event.Warning("cannot update ComponentDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &componentDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateComponentDefinition, componentDefinition.Name, err)))
|
||||
return err
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.latestRevision of the ComponentDefinition", "componentDefinition", klog.KRef(req.Namespace, req.Name),
|
||||
"Name", defRev.Name, "Revision", defRev.Spec.Revision, "RevisionHash", defRev.Spec.RevisionHash)
|
||||
return nil
|
||||
})
|
||||
if result != nil {
|
||||
return *result, err
|
||||
}
|
||||
|
||||
if err = coredef.CleanUpDefinitionRevision(ctx, r.Client, &componentDefinition, r.defRevLimit); err != nil {
|
||||
klog.InfoS("Failed to collect garbage", "err", err)
|
||||
r.record.Event(&componentDefinition, event.Warning("failed to garbage collect DefinitionRevision of type ComponentDefinition", err))
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
def := utils.NewCapabilityComponentDef(&componentDefinition)
|
||||
@@ -140,7 +101,6 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(componentDefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrStoreCapabilityInConfigMap, def.Name, err)))
|
||||
}
|
||||
|
||||
if componentDefinition.Status.ConfigMapRef != cmName {
|
||||
componentDefinition.Status.ConfigMapRef = cmName
|
||||
if err := r.UpdateStatus(ctx, &componentDefinition); err != nil {
|
||||
@@ -155,24 +115,6 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *Reconciler) createComponentDefRevision(ctx context.Context, componentDef *v1beta1.ComponentDefinition, defRev *v1beta1.DefinitionRevision) error {
|
||||
namespace := componentDef.GetNamespace()
|
||||
defRev.SetLabels(componentDef.GetLabels())
|
||||
defRev.SetLabels(util.MergeMapOverrideWithDst(defRev.Labels,
|
||||
map[string]string{oam.LabelComponentDefinitionName: componentDef.Name}))
|
||||
defRev.SetNamespace(namespace)
|
||||
|
||||
rev := &v1beta1.DefinitionRevision{}
|
||||
err := r.Client.Get(ctx, client.ObjectKey{Namespace: namespace, Name: defRev.Name}, rev)
|
||||
if apierrors.IsNotFound(err) {
|
||||
err = r.Create(ctx, defRev)
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1beta1.ComponentDefinition's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, def *v1beta1.ComponentDefinition, opts ...client.UpdateOption) error {
|
||||
status := def.DeepCopy().Status
|
||||
@@ -217,15 +159,3 @@ func parseOptions(args oamctrl.Args) options {
|
||||
controllerVersion: version.VelaVersion,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reconciler) matchControllerRequirement(componentDefinition *v1beta1.ComponentDefinition) bool {
|
||||
if componentDefinition.Annotations != nil {
|
||||
if requireVersion, ok := componentDefinition.Annotations[oam.AnnotationControllerRequirement]; ok {
|
||||
return requireVersion == r.controllerVersion
|
||||
}
|
||||
}
|
||||
if r.ignoreDefNoCtrlReq {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/klog/v2"
|
||||
@@ -40,9 +39,9 @@ import (
|
||||
oamctrl "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
|
||||
coredef "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/core"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/version"
|
||||
)
|
||||
|
||||
// Reconciler reconciles a PolicyDefinition object
|
||||
@@ -54,6 +53,8 @@ type Reconciler struct {
|
||||
record event.Recorder
|
||||
defRevLimit int
|
||||
concurrentReconciles int
|
||||
ignoreDefNoCtrlReq bool
|
||||
controllerVersion string
|
||||
}
|
||||
|
||||
// Reconcile is the main logic for PolicyDefinition controller
|
||||
@@ -64,85 +65,53 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
|
||||
definitionName := req.NamespacedName.Name
|
||||
klog.InfoS("Reconciling PolicyDefinition...", "Name", definitionName, "Namespace", req.Namespace)
|
||||
var policydefinition v1beta1.PolicyDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &policydefinition); err != nil {
|
||||
var policyDefinition v1beta1.PolicyDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &policyDefinition); err != nil {
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
// this is a placeholder for finalizer here in the future
|
||||
if policydefinition.DeletionTimestamp != nil {
|
||||
if policyDefinition.DeletionTimestamp != nil {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// refresh package discover when policyDefinition is registered
|
||||
if policydefinition.Spec.Reference.Name != "" {
|
||||
err := utils.RefreshPackageDiscover(ctx, r.Client, r.dm, r.pd, &policydefinition)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot refresh packageDiscover")
|
||||
r.record.Event(&policydefinition, event.Warning("cannot refresh packageDiscover", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &policydefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrRefreshPackageDiscover, err)))
|
||||
}
|
||||
if !coredef.MatchControllerRequirement(&policyDefinition, r.controllerVersion, r.ignoreDefNoCtrlReq) {
|
||||
klog.InfoS("skip definition: not match the controller requirement of definition", "policyDefinition", klog.KObj(&policyDefinition))
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// generate DefinitionRevision from policyDefinition
|
||||
defRev, isNewRevision, err := coredef.GenerateDefinitionRevision(ctx, r.Client, &policydefinition)
|
||||
defRev, result, err := coredef.ReconcileDefinitionRevision(ctx, r.Client, r.record, &policyDefinition, r.defRevLimit, func(revision *common.Revision) error {
|
||||
policyDefinition.Status.LatestRevision = revision
|
||||
if err := r.UpdateStatus(ctx, &policyDefinition); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if result != nil {
|
||||
return *result, err
|
||||
}
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot generate DefinitionRevision", "PolicyDefinitionName", policydefinition.Name)
|
||||
r.record.Event(&policydefinition, event.Warning("cannot generate DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &policydefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrGenerateDefinitionRevision, policydefinition.Name, err)))
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
if isNewRevision {
|
||||
if err = r.createPolicyDefRevision(ctx, &policydefinition, defRev); err != nil {
|
||||
klog.ErrorS(err, "cannot create DefinitionRevision")
|
||||
r.record.Event(&(policydefinition), event.Warning("cannot create DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(policydefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrCreateDefinitionRevision, defRev.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully created PolicyDefRevision", "name", defRev.Name)
|
||||
|
||||
policydefinition.Status.LatestRevision = &common.Revision{
|
||||
Name: defRev.Name,
|
||||
Revision: defRev.Spec.Revision,
|
||||
RevisionHash: defRev.Spec.RevisionHash,
|
||||
}
|
||||
|
||||
if err := r.UpdateStatus(ctx, &policydefinition); err != nil {
|
||||
klog.ErrorS(err, "cannot update PolicyDefinition Status")
|
||||
r.record.Event(&(policydefinition), event.Warning("cannot update PolicyDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(policydefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdatePolicyDefinition, policydefinition.Name, err)))
|
||||
}
|
||||
|
||||
klog.InfoS("Successfully updated the status.latestRevision of the PolicyDefinition", "policyDefinition", klog.KRef(req.Namespace, req.Name),
|
||||
"Name", defRev.Name, "Revision", defRev.Spec.Revision, "RevisionHash", defRev.Spec.RevisionHash)
|
||||
}
|
||||
|
||||
if err := coredef.CleanUpDefinitionRevision(ctx, r.Client, &policydefinition, r.defRevLimit); err != nil {
|
||||
klog.Error("[Garbage collection]")
|
||||
r.record.Event(&policydefinition, event.Warning("failed to garbage collect DefinitionRevision of type PolicyDefinition", err))
|
||||
}
|
||||
|
||||
def := utils.NewCapabilityPolicyDef(&policydefinition)
|
||||
def := utils.NewCapabilityPolicyDef(&policyDefinition)
|
||||
def.Name = req.NamespacedName.Name
|
||||
// Store the parameter of policyDefinition to configMap
|
||||
cmName, err := def.StoreOpenAPISchema(ctx, r.Client, r.pd, req.Namespace, req.Name, defRev.Name)
|
||||
if err != nil {
|
||||
klog.InfoS("Could not capability in ConfigMap", "err", err)
|
||||
r.record.Event(&(policydefinition), event.Warning("Could not store capability in ConfigMap", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(policydefinition),
|
||||
r.record.Event(&(policyDefinition), event.Warning("Could not store capability in ConfigMap", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(policyDefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrStoreCapabilityInConfigMap, def.Name, err)))
|
||||
}
|
||||
|
||||
if policydefinition.Status.ConfigMapRef != cmName {
|
||||
policydefinition.Status.ConfigMapRef = cmName
|
||||
if err := r.UpdateStatus(ctx, &policydefinition); err != nil {
|
||||
if policyDefinition.Status.ConfigMapRef != cmName {
|
||||
policyDefinition.Status.ConfigMapRef = cmName
|
||||
if err := r.UpdateStatus(ctx, &policyDefinition); err != nil {
|
||||
klog.InfoS("Could not update policyDefinition Status", "err", err)
|
||||
r.record.Event(&policydefinition, event.Warning("cannot update PolicyDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &policydefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdatePolicyDefinition, policydefinition.Name, err)))
|
||||
r.record.Event(&policyDefinition, event.Warning("cannot update PolicyDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &policyDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdatePolicyDefinition, policyDefinition.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.configMapRef of the PolicyDefinition", "policyDefinition",
|
||||
klog.KRef(req.Namespace, req.Name), "status.configMapRef", cmName)
|
||||
@@ -151,24 +120,6 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *Reconciler) createPolicyDefRevision(ctx context.Context, def *v1beta1.PolicyDefinition, defRev *v1beta1.DefinitionRevision) error {
|
||||
namespace := def.GetNamespace()
|
||||
defRev.SetLabels(def.GetLabels())
|
||||
defRev.SetLabels(util.MergeMapOverrideWithDst(defRev.Labels,
|
||||
map[string]string{oam.LabelPolicyDefinitionName: def.Name}))
|
||||
defRev.SetNamespace(namespace)
|
||||
|
||||
rev := &v1beta1.DefinitionRevision{}
|
||||
err := r.Client.Get(ctx, client.ObjectKey{Namespace: namespace, Name: defRev.Name}, rev)
|
||||
if apierrors.IsNotFound(err) {
|
||||
err = r.Create(ctx, defRev)
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1beta1.PolicyDefinition's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, def *v1beta1.PolicyDefinition, opts ...client.UpdateOption) error {
|
||||
status := def.DeepCopy().Status
|
||||
@@ -202,6 +153,8 @@ func Setup(mgr ctrl.Manager, args oamctrl.Args) error {
|
||||
pd: args.PackageDiscover,
|
||||
defRevLimit: args.DefRevisionLimit,
|
||||
concurrentReconciles: args.ConcurrentReconciles,
|
||||
ignoreDefNoCtrlReq: args.IgnoreDefinitionWithoutControllerRequirement,
|
||||
controllerVersion: version.VelaVersion,
|
||||
}
|
||||
return r.SetupWithManager(mgr)
|
||||
}
|
||||
|
||||
35
pkg/controller/core.oam.dev/v1alpha2/core/requirement.go
Normal file
35
pkg/controller/core.oam.dev/v1alpha2/core/requirement.go
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2022 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
// MatchControllerRequirement check the requirement
|
||||
func MatchControllerRequirement(definition util.ConditionedObject, controllerVersion string, ignoreDefNoCtrlReq bool) bool {
|
||||
if definition.GetAnnotations() != nil {
|
||||
if requireVersion, ok := definition.GetAnnotations()[oam.AnnotationControllerRequirement]; ok {
|
||||
return requireVersion == controllerVersion
|
||||
}
|
||||
}
|
||||
if ignoreDefNoCtrlReq {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
"github.com/pkg/errors"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -29,12 +30,15 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/condition"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
// GenerateDefinitionRevision will generate a definition revision the generated revision
|
||||
@@ -321,3 +325,86 @@ func (h historiesByRevision) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
|
||||
func (h historiesByRevision) Less(i, j int) bool {
|
||||
return h[i].Spec.Revision < h[j].Spec.Revision
|
||||
}
|
||||
|
||||
// ReconcileDefinitionRevision generate the definition revision and update it.
|
||||
func ReconcileDefinitionRevision(ctx context.Context,
|
||||
cli client.Client,
|
||||
record event.Recorder,
|
||||
definition util.ConditionedObject,
|
||||
revisionLimit int,
|
||||
updateLatestRevision func(*common.Revision) error,
|
||||
) (*v1beta1.DefinitionRevision, *ctrl.Result, error) {
|
||||
|
||||
// generate DefinitionRevision from componentDefinition
|
||||
defRev, isNewRevision, err := GenerateDefinitionRevision(ctx, cli, definition)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Could not generate DefinitionRevision", "componentDefinition", klog.KObj(definition))
|
||||
record.Event(definition, event.Warning("Could not generate DefinitionRevision", err))
|
||||
return nil, &ctrl.Result{}, util.PatchCondition(ctx, cli, definition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrGenerateDefinitionRevision, definition.GetName(), err)))
|
||||
}
|
||||
|
||||
if isNewRevision {
|
||||
if err := CreateDefinitionRevision(ctx, cli, definition, defRev.DeepCopy()); err != nil {
|
||||
klog.ErrorS(err, "Could not create DefinitionRevision")
|
||||
record.Event(definition, event.Warning("cannot create DefinitionRevision", err))
|
||||
return nil, &ctrl.Result{}, util.PatchCondition(ctx, cli, definition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrCreateDefinitionRevision, defRev.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully created definitionRevision", "definitionRevision", klog.KObj(defRev))
|
||||
|
||||
if err := updateLatestRevision(&common.Revision{
|
||||
Name: defRev.Name,
|
||||
Revision: defRev.Spec.Revision,
|
||||
RevisionHash: defRev.Spec.RevisionHash,
|
||||
}); err != nil {
|
||||
klog.ErrorS(err, "Could not update Definition Status")
|
||||
record.Event(definition, event.Warning("cannot update the definition status", err))
|
||||
return nil, &ctrl.Result{}, util.PatchCondition(ctx, cli, definition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateComponentDefinition, definition.GetName(), err)))
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.latestRevision of the definition", "Definition", klog.KRef(definition.GetNamespace(), definition.GetName()),
|
||||
"Name", defRev.Name, "Revision", defRev.Spec.Revision, "RevisionHash", defRev.Spec.RevisionHash)
|
||||
}
|
||||
|
||||
if err = CleanUpDefinitionRevision(ctx, cli, definition, revisionLimit); err != nil {
|
||||
klog.InfoS("Failed to collect garbage", "err", err)
|
||||
record.Event(definition, event.Warning("failed to garbage collect DefinitionRevision of type ComponentDefinition", err))
|
||||
}
|
||||
return defRev, nil, nil
|
||||
}
|
||||
|
||||
// CreateDefinitionRevision create the revision of the definition
|
||||
func CreateDefinitionRevision(ctx context.Context, cli client.Client, def util.ConditionedObject, defRev *v1beta1.DefinitionRevision) error {
|
||||
namespace := def.GetNamespace()
|
||||
defRev.SetLabels(def.GetLabels())
|
||||
|
||||
var labelKey string
|
||||
switch def.(type) {
|
||||
case *v1beta1.ComponentDefinition:
|
||||
labelKey = oam.LabelComponentDefinitionName
|
||||
case *v1beta1.TraitDefinition:
|
||||
labelKey = oam.LabelTraitDefinitionName
|
||||
case *v1beta1.PolicyDefinition:
|
||||
labelKey = oam.LabelPolicyDefinitionName
|
||||
case *v1beta1.WorkflowStepDefinition:
|
||||
labelKey = oam.LabelWorkflowStepDefinitionName
|
||||
}
|
||||
if labelKey != "" {
|
||||
defRev.SetLabels(util.MergeMapOverrideWithDst(defRev.Labels, map[string]string{labelKey: def.GetName()}))
|
||||
} else {
|
||||
defRev.SetLabels(defRev.Labels)
|
||||
}
|
||||
|
||||
defRev.SetNamespace(namespace)
|
||||
|
||||
rev := &v1beta1.DefinitionRevision{}
|
||||
err := cli.Get(ctx, client.ObjectKey{Namespace: namespace, Name: defRev.Name}, rev)
|
||||
if apierrors.IsNotFound(err) {
|
||||
err = cli.Create(ctx, defRev)
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/klog/v2"
|
||||
@@ -40,7 +39,6 @@ import (
|
||||
oamctrl "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
|
||||
coredef "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/core"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/version"
|
||||
@@ -70,89 +68,54 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
|
||||
klog.InfoS("Reconcile traitDefinition", "traitDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
|
||||
var traitdefinition v1beta1.TraitDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &traitdefinition); err != nil {
|
||||
var traitDefinition v1beta1.TraitDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &traitDefinition); err != nil {
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
if !r.matchControllerRequirement(&traitdefinition) {
|
||||
klog.InfoS("skip traitDefinition: not match the controller requirement of traitDefinition", "traitDefinition", klog.KObj(&traitdefinition))
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// this is a placeholder for finalizer here in the future
|
||||
if traitdefinition.DeletionTimestamp != nil {
|
||||
if traitDefinition.DeletionTimestamp != nil {
|
||||
klog.InfoS("The TraitDefinition is being deleted", "traitDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// refresh package discover when traitDefinition is registered
|
||||
if traitdefinition.Spec.Reference.Name != "" {
|
||||
err := utils.RefreshPackageDiscover(ctx, r.Client, r.dm, r.pd, &traitdefinition)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Could not refresh packageDiscover", "traitDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
r.record.Event(&traitdefinition, event.Warning("cannot refresh packageDiscover", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrRefreshPackageDiscover, err)))
|
||||
}
|
||||
if !coredef.MatchControllerRequirement(&traitDefinition, r.controllerVersion, r.ignoreDefNoCtrlReq) {
|
||||
klog.InfoS("skip definition: not match the controller requirement of definition", "traitDefinition", klog.KObj(&traitDefinition))
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// generate DefinitionRevision from traitDefinition
|
||||
defRev, isNewRevision, err := coredef.GenerateDefinitionRevision(ctx, r.Client, &traitdefinition)
|
||||
defRev, result, err := coredef.ReconcileDefinitionRevision(ctx, r.Client, r.record, &traitDefinition, r.defRevLimit, func(revision *common.Revision) error {
|
||||
traitDefinition.Status.LatestRevision = revision
|
||||
if err := r.UpdateStatus(ctx, &traitDefinition); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if result != nil {
|
||||
return *result, err
|
||||
}
|
||||
if err != nil {
|
||||
klog.InfoS("Could not generate definitionRevision", "traitDefinition", klog.KObj(&traitdefinition), "err", err)
|
||||
r.record.Event(&traitdefinition, event.Warning("Could not generate DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrGenerateDefinitionRevision, traitdefinition.Name, err)))
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
if isNewRevision {
|
||||
if err := r.createTraitDefRevision(ctx, &traitdefinition, defRev); err != nil {
|
||||
klog.ErrorS(err, "Could not create DefinitionRevision")
|
||||
r.record.Event(&traitdefinition, event.Warning("Could not create definitionRevision", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrCreateDefinitionRevision, defRev.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully created definitionRevision", "definitionRevision", klog.KObj(defRev))
|
||||
|
||||
traitdefinition.Status.LatestRevision = &common.Revision{
|
||||
Name: defRev.Name,
|
||||
Revision: defRev.Spec.Revision,
|
||||
RevisionHash: defRev.Spec.RevisionHash,
|
||||
}
|
||||
if err := r.UpdateStatus(ctx, &traitdefinition); err != nil {
|
||||
klog.ErrorS(err, "Could not update TraitDefinition Status", "traitDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
r.record.Event(&traitdefinition, event.Warning("Could not update TraitDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateTraitDefinition, traitdefinition.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.latestRevision of the TraitDefinition", "traitDefinition", klog.KRef(req.Namespace, req.Name),
|
||||
"Name", defRev.Name, "Revision", defRev.Spec.Revision, "RevisionHash", defRev.Spec.RevisionHash)
|
||||
}
|
||||
|
||||
if err := coredef.CleanUpDefinitionRevision(ctx, r.Client, &traitdefinition, r.defRevLimit); err != nil {
|
||||
klog.InfoS("Failed to collect garbage", "err", err)
|
||||
r.record.Event(&traitdefinition, event.Warning("Failed to garbage collect DefinitionRevision of type TraitDefinition", err))
|
||||
}
|
||||
|
||||
def := utils.NewCapabilityTraitDef(&traitdefinition)
|
||||
def := utils.NewCapabilityTraitDef(&traitDefinition)
|
||||
def.Name = req.NamespacedName.Name
|
||||
// Store the parameter of traitDefinition to configMap
|
||||
cmName, err := def.StoreOpenAPISchema(ctx, r.Client, r.pd, req.Namespace, req.Name, defRev.Name)
|
||||
if err != nil {
|
||||
klog.InfoS("Could not store capability in ConfigMap", "err", err)
|
||||
r.record.Event(&(traitdefinition), event.Warning("Could not store capability in ConfigMap", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrStoreCapabilityInConfigMap, traitdefinition.Name, err)))
|
||||
r.record.Event(&(traitDefinition), event.Warning("Could not store capability in ConfigMap", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrStoreCapabilityInConfigMap, traitDefinition.Name, err)))
|
||||
}
|
||||
|
||||
if traitdefinition.Status.ConfigMapRef != cmName {
|
||||
traitdefinition.Status.ConfigMapRef = cmName
|
||||
if err := r.UpdateStatus(ctx, &traitdefinition); err != nil {
|
||||
if traitDefinition.Status.ConfigMapRef != cmName {
|
||||
traitDefinition.Status.ConfigMapRef = cmName
|
||||
if err := r.UpdateStatus(ctx, &traitDefinition); err != nil {
|
||||
klog.ErrorS(err, "Could not update TraitDefinition Status", "traitDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
r.record.Event(&traitdefinition, event.Warning("Could not update TraitDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateTraitDefinition, traitdefinition.Name, err)))
|
||||
r.record.Event(&traitDefinition, event.Warning("Could not update TraitDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &traitDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateTraitDefinition, traitDefinition.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.configMapRef of the TraitDefinition", "traitDefinition",
|
||||
klog.KRef(req.Namespace, req.Name), "status.configMapRef", cmName)
|
||||
@@ -160,25 +123,6 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *Reconciler) createTraitDefRevision(ctx context.Context, traitDef *v1beta1.TraitDefinition, defRev *v1beta1.DefinitionRevision) error {
|
||||
namespace := traitDef.GetNamespace()
|
||||
|
||||
defRev.SetLabels(traitDef.GetLabels())
|
||||
defRev.SetLabels(util.MergeMapOverrideWithDst(defRev.Labels,
|
||||
map[string]string{oam.LabelTraitDefinitionName: traitDef.Name}))
|
||||
defRev.SetNamespace(namespace)
|
||||
|
||||
rev := &v1beta1.DefinitionRevision{}
|
||||
err := r.Client.Get(ctx, client.ObjectKey{Namespace: namespace, Name: defRev.Name}, rev)
|
||||
if apierrors.IsNotFound(err) {
|
||||
err = r.Create(ctx, defRev)
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1beta1.TraitDefinition's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, def *v1beta1.TraitDefinition, opts ...client.UpdateOption) error {
|
||||
status := def.DeepCopy().Status
|
||||
@@ -223,15 +167,3 @@ func parseOptions(args oamctrl.Args) options {
|
||||
controllerVersion: version.VelaVersion,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reconciler) matchControllerRequirement(traitDefinition *v1beta1.TraitDefinition) bool {
|
||||
if traitDefinition.Annotations != nil {
|
||||
if requireVersion, ok := traitDefinition.Annotations[oam.AnnotationControllerRequirement]; ok {
|
||||
return requireVersion == r.controllerVersion
|
||||
}
|
||||
}
|
||||
if r.ignoreDefNoCtrlReq {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"k8s.io/klog/v2"
|
||||
@@ -40,7 +39,6 @@ import (
|
||||
oamctrl "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
|
||||
coredef "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/core"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/version"
|
||||
@@ -71,88 +69,53 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
definitionName := req.NamespacedName.Name
|
||||
klog.InfoS("Reconciling WorkflowStepDefinition...", "Name", definitionName, "Namespace", req.Namespace)
|
||||
|
||||
var wfstepdefinition v1beta1.WorkflowStepDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &wfstepdefinition); err != nil {
|
||||
var wfStepDefinition v1beta1.WorkflowStepDefinition
|
||||
if err := r.Get(ctx, req.NamespacedName, &wfStepDefinition); err != nil {
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
if !r.matchControllerRequirement(&wfstepdefinition) {
|
||||
klog.InfoS("skip workflowStepDefinition: not match the controller requirement of workflowStepDefinition", "workflowStepDefinition", klog.KObj(&wfstepdefinition))
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// this is a placeholder for finalizer here in the future
|
||||
if wfstepdefinition.DeletionTimestamp != nil {
|
||||
if wfStepDefinition.DeletionTimestamp != nil {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// refresh package discover when WorkflowStepDefinition is registered
|
||||
if wfstepdefinition.Spec.Reference.Name != "" {
|
||||
err := utils.RefreshPackageDiscover(ctx, r.Client, r.dm, r.pd, &wfstepdefinition)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot refresh packageDiscover")
|
||||
r.record.Event(&wfstepdefinition, event.Warning("cannot refresh packageDiscover", err))
|
||||
return ctrl.Result{}, util.EndReconcileWithNegativeCondition(ctx, r, &wfstepdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrRefreshPackageDiscover, err)))
|
||||
}
|
||||
if !coredef.MatchControllerRequirement(&wfStepDefinition, r.controllerVersion, r.ignoreDefNoCtrlReq) {
|
||||
klog.InfoS("skip definition: not match the controller requirement of definition", "workflowStepDefinition", klog.KObj(&wfStepDefinition))
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
defRev, result, err := coredef.ReconcileDefinitionRevision(ctx, r.Client, r.record, &wfStepDefinition, r.defRevLimit, func(revision *common.Revision) error {
|
||||
wfStepDefinition.Status.LatestRevision = revision
|
||||
if err := r.UpdateStatus(ctx, &wfStepDefinition); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if result != nil {
|
||||
return *result, err
|
||||
}
|
||||
// generate DefinitionRevision from WorkflowStepDefinition
|
||||
defRev, isNewRevision, err := coredef.GenerateDefinitionRevision(ctx, r.Client, &wfstepdefinition)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot generate DefinitionRevision", "WorkflowStepDefinitionName", wfstepdefinition.Name)
|
||||
r.record.Event(&wfstepdefinition, event.Warning("cannot generate DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &wfstepdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrGenerateDefinitionRevision, wfstepdefinition.Name, err)))
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
if isNewRevision {
|
||||
if err = r.createWFStepDefRevision(ctx, &wfstepdefinition, defRev); err != nil {
|
||||
klog.ErrorS(err, "cannot create DefinitionRevision")
|
||||
r.record.Event(&(wfstepdefinition), event.Warning("cannot create DefinitionRevision", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(wfstepdefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrCreateDefinitionRevision, defRev.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully created WFStepDefRevision", "name", defRev.Name)
|
||||
|
||||
wfstepdefinition.Status.LatestRevision = &common.Revision{
|
||||
Name: defRev.Name,
|
||||
Revision: defRev.Spec.Revision,
|
||||
RevisionHash: defRev.Spec.RevisionHash,
|
||||
}
|
||||
if err := r.UpdateStatus(ctx, &wfstepdefinition); err != nil {
|
||||
klog.ErrorS(err, "cannot update WorkflowStepDefinition Status")
|
||||
r.record.Event(&(wfstepdefinition), event.Warning("cannot update WorkflowStepDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &(wfstepdefinition),
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateWorkflowStepDefinition, wfstepdefinition.Name, err)))
|
||||
}
|
||||
|
||||
klog.InfoS("Successfully updated the status.latestRevision of the WorkflowStepDefinition", "WorkflowStepDefinition", klog.KRef(req.Namespace, req.Name),
|
||||
"Name", defRev.Name, "Revision", defRev.Spec.Revision, "RevisionHash", defRev.Spec.RevisionHash)
|
||||
}
|
||||
|
||||
if err := coredef.CleanUpDefinitionRevision(ctx, r.Client, &wfstepdefinition, r.defRevLimit); err != nil {
|
||||
klog.Error("[Garbage collection]")
|
||||
r.record.Event(&wfstepdefinition, event.Warning("failed to garbage collect DefinitionRevision of type WorkflowStepDefinition", err))
|
||||
}
|
||||
|
||||
def := utils.NewCapabilityStepDef(&wfstepdefinition)
|
||||
def := utils.NewCapabilityStepDef(&wfStepDefinition)
|
||||
def.Name = req.NamespacedName.Name
|
||||
// Store the parameter of stepDefinition to configMap
|
||||
cmName, err := def.StoreOpenAPISchema(ctx, r.Client, r.pd, req.Namespace, req.Name, defRev.Name)
|
||||
if err != nil {
|
||||
klog.InfoS("Could not store capability in ConfigMap", "err", err)
|
||||
r.record.Event(&(wfstepdefinition), event.Warning("Could not store capability in ConfigMap", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &wfstepdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrStoreCapabilityInConfigMap, wfstepdefinition.Name, err)))
|
||||
r.record.Event(&(wfStepDefinition), event.Warning("Could not store capability in ConfigMap", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &wfStepDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrStoreCapabilityInConfigMap, wfStepDefinition.Name, err)))
|
||||
}
|
||||
|
||||
if wfstepdefinition.Status.ConfigMapRef != cmName {
|
||||
wfstepdefinition.Status.ConfigMapRef = cmName
|
||||
if err := r.UpdateStatus(ctx, &wfstepdefinition); err != nil {
|
||||
if wfStepDefinition.Status.ConfigMapRef != cmName {
|
||||
wfStepDefinition.Status.ConfigMapRef = cmName
|
||||
if err := r.UpdateStatus(ctx, &wfStepDefinition); err != nil {
|
||||
klog.ErrorS(err, "Could not update WorkflowStepDefinition Status", "workflowStepDefinition", klog.KRef(req.Namespace, req.Name))
|
||||
r.record.Event(&wfstepdefinition, event.Warning("Could not update WorkflowStepDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &wfstepdefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateWorkflowStepDefinition, wfstepdefinition.Name, err)))
|
||||
r.record.Event(&wfStepDefinition, event.Warning("Could not update WorkflowStepDefinition Status", err))
|
||||
return ctrl.Result{}, util.PatchCondition(ctx, r, &wfStepDefinition,
|
||||
condition.ReconcileError(fmt.Errorf(util.ErrUpdateWorkflowStepDefinition, wfStepDefinition.Name, err)))
|
||||
}
|
||||
klog.InfoS("Successfully updated the status.configMapRef of the WorkflowStepDefinition", "workflowStepDefinition",
|
||||
klog.KRef(req.Namespace, req.Name), "status.configMapRef", cmName)
|
||||
@@ -160,24 +123,6 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *Reconciler) createWFStepDefRevision(ctx context.Context, def *v1beta1.WorkflowStepDefinition, defRev *v1beta1.DefinitionRevision) error {
|
||||
namespace := def.GetNamespace()
|
||||
defRev.SetLabels(def.GetLabels())
|
||||
defRev.SetLabels(util.MergeMapOverrideWithDst(defRev.Labels,
|
||||
map[string]string{oam.LabelWorkflowStepDefinitionName: def.Name}))
|
||||
defRev.SetNamespace(namespace)
|
||||
|
||||
rev := &v1beta1.DefinitionRevision{}
|
||||
err := r.Client.Get(ctx, client.ObjectKey{Namespace: namespace, Name: defRev.Name}, rev)
|
||||
if apierrors.IsNotFound(err) {
|
||||
err = r.Create(ctx, defRev)
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateStatus updates v1beta1.WorkflowStepDefinition's Status with retry.RetryOnConflict
|
||||
func (r *Reconciler) UpdateStatus(ctx context.Context, def *v1beta1.WorkflowStepDefinition, opts ...client.UpdateOption) error {
|
||||
status := def.DeepCopy().Status
|
||||
@@ -222,15 +167,3 @@ func parseOptions(args oamctrl.Args) options {
|
||||
controllerVersion: version.VelaVersion,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reconciler) matchControllerRequirement(wfstepdefinition *v1beta1.WorkflowStepDefinition) bool {
|
||||
if wfstepdefinition.Annotations != nil {
|
||||
if requireVersion, ok := wfstepdefinition.Annotations[oam.AnnotationControllerRequirement]; ok {
|
||||
return requireVersion == r.controllerVersion
|
||||
}
|
||||
}
|
||||
if r.ignoreDefNoCtrlReq {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -258,6 +258,7 @@ func ComputeSpecHash(spec interface{}) (string, error) {
|
||||
}
|
||||
|
||||
// RefreshPackageDiscover help refresh package discover
|
||||
// Deprecated: The function RefreshKubePackagesFromCluster affects performance and the code has been commented a long time.
|
||||
func RefreshPackageDiscover(ctx context.Context, k8sClient client.Client, dm discoverymapper.DiscoveryMapper,
|
||||
pd *packages.PackageDiscover, definition runtime.Object) error {
|
||||
var gvk metav1.GroupVersionKind
|
||||
|
||||
Reference in New Issue
Block a user