mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-18 03:56:36 +00:00
Merge pull request #963 from ryanzhang-oss/appDeployment-structure
further develop appDeployment controller
This commit is contained in:
@@ -29,8 +29,8 @@ type ApplicationDeploymentSpec struct {
|
||||
TargetApplicationName string `json:"targetApplicationName"`
|
||||
|
||||
// SourceApplicationName contains the name of the application that we need to upgrade from.
|
||||
// it can be omitted only when it's the first time to deploy the application
|
||||
SourceApplicationName *string `json:"sourceApplicationName,omitempty"`
|
||||
// it can be empty only when it's the first time to deploy the application
|
||||
SourceApplicationName string `json:"sourceApplicationName"`
|
||||
|
||||
// The list of component to upgrade in the application.
|
||||
// We only support single component application so far
|
||||
|
||||
@@ -321,11 +321,6 @@ func (in *ApplicationDeploymentList) DeepCopyObject() runtime.Object {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ApplicationDeploymentSpec) DeepCopyInto(out *ApplicationDeploymentSpec) {
|
||||
*out = *in
|
||||
if in.SourceApplicationName != nil {
|
||||
in, out := &in.SourceApplicationName, &out.SourceApplicationName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ComponentList != nil {
|
||||
in, out := &in.ComponentList, &out.ComponentList
|
||||
*out = make([]string, len(*in))
|
||||
|
||||
@@ -251,13 +251,14 @@ spec:
|
||||
type: integer
|
||||
type: object
|
||||
sourceApplicationName:
|
||||
description: SourceApplicationName contains the name of the application that we need to upgrade from. it can be omitted only when it's the first time to deploy the application
|
||||
description: SourceApplicationName contains the name of the application that we need to upgrade from. it can be empty only when it's the first time to deploy the application
|
||||
type: string
|
||||
targetApplicationName:
|
||||
description: TargetApplicationName contains the name of the application that we need to upgrade to. We assume that an application is immutable, thus the name alone is suffice
|
||||
type: string
|
||||
required:
|
||||
- rolloutPlan
|
||||
- sourceApplicationName
|
||||
- targetApplicationName
|
||||
type: object
|
||||
status:
|
||||
|
||||
@@ -174,7 +174,7 @@ We will use a pre-defined annotation "app.oam.dev/rollout" that equals to "true"
|
||||
utilizes an appDeployment object to follow this rule.
|
||||
- Upon creation, the appDeployment controller marks itself as the owner of the application. The
|
||||
application controller will have built-in logic to ignore any applications that has the
|
||||
"app.oam.dev/rollout" annotation set to true.
|
||||
"app.oam.dev/rollout-template" annotation set to true.
|
||||
- The appDeployment controller can change the target application fields. For example,
|
||||
- It might remove all the conflict traits, such as HPA during upgrade.
|
||||
- It might modify the label selectors fields in the services to make sure there are ways to
|
||||
|
||||
@@ -251,13 +251,14 @@ spec:
|
||||
type: integer
|
||||
type: object
|
||||
sourceApplicationName:
|
||||
description: SourceApplicationName contains the name of the application that we need to upgrade from. it can be omitted only when it's the first time to deploy the application
|
||||
description: SourceApplicationName contains the name of the application that we need to upgrade from. it can be empty only when it's the first time to deploy the application
|
||||
type: string
|
||||
targetApplicationName:
|
||||
description: TargetApplicationName contains the name of the application that we need to upgrade to. We assume that an application is immutable, thus the name alone is suffice
|
||||
type: string
|
||||
required:
|
||||
- rolloutPlan
|
||||
- sourceApplicationName
|
||||
- targetApplicationName
|
||||
type: object
|
||||
status:
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package rollout
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
|
||||
)
|
||||
|
||||
// ReconcileRolloutPlan generates the rollout plan and reconcile it
|
||||
func ReconcileRolloutPlan(ctx context.Context, client client.Client, rolloutSpec *v1alpha1.RolloutPlan,
|
||||
targetWorkload, sourceWorkload *unstructured.Unstructured) error {
|
||||
klog.InfoS("generate the rollout plan", "rollout Spec", rolloutSpec,
|
||||
"target workload", klog.KObj(targetWorkload))
|
||||
return nil
|
||||
}
|
||||
@@ -36,7 +36,8 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
)
|
||||
|
||||
const rolloutReconcileWaitTime = time.Second * 30
|
||||
// RolloutReconcileWaitTime is the time to wait before reconcile again an application still in rollout phase
|
||||
const RolloutReconcileWaitTime = time.Second * 3
|
||||
|
||||
// Reconciler reconciles a Application object
|
||||
type Reconciler struct {
|
||||
@@ -75,7 +76,7 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
app.Status.Phase = v1alpha2.ApplicationRollingOut
|
||||
app.Status.SetConditions(readyCondition("Rolling"))
|
||||
// do not process apps still in rolling out
|
||||
return ctrl.Result{RequeueAfter: rolloutReconcileWaitTime}, r.Status().Update(ctx, app)
|
||||
return ctrl.Result{RequeueAfter: RolloutReconcileWaitTime}, r.Status().Update(ctx, app)
|
||||
}
|
||||
|
||||
applog.Info("Start Rendering")
|
||||
|
||||
@@ -679,7 +679,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
Namespace: app.Namespace,
|
||||
}
|
||||
result, err := reconciler.Reconcile(reconcile.Request{NamespacedName: appKey})
|
||||
Expect(result).To(BeIdenticalTo(ctrl.Result{RequeueAfter: rolloutReconcileWaitTime}))
|
||||
Expect(result).To(BeIdenticalTo(ctrl.Result{RequeueAfter: RolloutReconcileWaitTime}))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
By("Check App status is rollingout")
|
||||
checkApp := &v1alpha2.Application{}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package applicationdeployment
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
corev1alpha2 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
// adjustTargetApplicationTemplate makes sure that the target template is in compliance before handing it over to
|
||||
// the application controller
|
||||
func (r *Reconciler) adjustTargetApplicationTemplate(ctx context.Context, targetWorkload *unstructured.Unstructured,
|
||||
targetApp *corev1alpha2.Application) error {
|
||||
klog.InfoS("Start to adjust the target application template",
|
||||
"application", klog.KObj(targetApp), "target workload", targetWorkload)
|
||||
|
||||
// TODO: adjust the target workload if needed
|
||||
|
||||
// update the template without the rollout annotation so that the application controller can take over
|
||||
anno := targetApp.GetAnnotations()
|
||||
delete(anno, oam.AnnotationAppRollout)
|
||||
targetApp.SetAnnotations(anno)
|
||||
return r.Update(ctx, targetApp)
|
||||
}
|
||||
+24
-13
@@ -7,22 +7,23 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
corev1alpha2 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
|
||||
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
appUtil "github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1alpha2/applicationdeployment"
|
||||
)
|
||||
|
||||
// extractWorkload extracts the workload
|
||||
func (r *Reconciler) extractWorkload(componentList []string, targetApp,
|
||||
sourceApp *corev1alpha2.Application) (*unstructured.Unstructured, *unstructured.Unstructured, error) {
|
||||
// extractWorkloadTypeAndGVK extracts the workload type and gvk
|
||||
func (r *Reconciler) extractWorkloadTypeAndGVK(ctx context.Context, componentList []string, targetApp,
|
||||
sourceApp *corev1alpha2.Application) (string, *schema.GroupVersionKind, error) {
|
||||
var componentType string
|
||||
// assume that the validator webhook has already guaranteed that there is no more than one component for now
|
||||
if len(componentList) == 0 {
|
||||
// we need to find a default component
|
||||
commons := appUtil.FindCommonComponent(targetApp, sourceApp)
|
||||
if len(commons) != 1 {
|
||||
return nil, nil, fmt.Errorf("cannot find a default component, too many common components: %+v", commons)
|
||||
return "", nil, fmt.Errorf("cannot find a default component, too many common components: %+v", commons)
|
||||
}
|
||||
componentType = commons[0]
|
||||
} else {
|
||||
@@ -30,33 +31,44 @@ func (r *Reconciler) extractWorkload(componentList []string, targetApp,
|
||||
}
|
||||
// get the workload definition
|
||||
// the validator webhook has checked that source and the target are the same type
|
||||
wd, err := oamutil.GetWorkloadDefinition(r, componentType)
|
||||
wd, err := oamutil.GetWorkloadDefinition(ctx, r, componentType)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, fmt.Sprintf("failed to get workload definition %s", componentType))
|
||||
return "", nil, errors.Wrap(err, fmt.Sprintf("failed to get workload definition %s", componentType))
|
||||
}
|
||||
// get the CR kind from the definitionRef
|
||||
gvk, err := oamutil.GetGVKFromDefinition(r.dm, wd.Spec.Reference)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, fmt.Sprintf("failed to get workload GVK from definition ref %s",
|
||||
return "", nil, errors.Wrap(err, fmt.Sprintf("failed to get workload GVK from definition ref %s",
|
||||
wd.Spec.Reference))
|
||||
}
|
||||
targetWorkload, err := r.fetchWorkload(targetApp, componentType, gvk)
|
||||
return componentType, &gvk, nil
|
||||
}
|
||||
|
||||
// fetchWorkload based on the component type and the application and its gvk
|
||||
func (r *Reconciler) fetchWorkloads(ctx context.Context, targetApp, sourceApp *corev1alpha2.Application, workloadType string,
|
||||
workloadGVK *schema.GroupVersionKind) (*unstructured.Unstructured, *unstructured.Unstructured, error) {
|
||||
targetWorkload, err := r.fetchWorkload(ctx, targetApp, workloadType, *workloadGVK)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
klog.InfoS("get the target workload we need to work on", "targetWorkload", klog.KObj(targetWorkload))
|
||||
|
||||
if sourceApp == nil {
|
||||
return targetWorkload, nil, nil
|
||||
}
|
||||
// get the component definition in the app,
|
||||
sourceWorkload, err := r.fetchWorkload(sourceApp, componentType, gvk)
|
||||
sourceWorkload, err := r.fetchWorkload(ctx, sourceApp, workloadType, *workloadGVK)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if sourceWorkload != nil {
|
||||
klog.InfoS("get the source workload we need to work on", "sourceWorkload", klog.KObj(sourceWorkload))
|
||||
}
|
||||
|
||||
return targetWorkload, sourceWorkload, nil
|
||||
}
|
||||
|
||||
// fetchWorkload based on the component type and the application and its gvk
|
||||
func (r *Reconciler) fetchWorkload(app *corev1alpha2.Application, componentType string,
|
||||
func (r *Reconciler) fetchWorkload(ctx context.Context, app *corev1alpha2.Application, componentType string,
|
||||
gvk schema.GroupVersionKind) (*unstructured.Unstructured, error) {
|
||||
// get the component definition in the app,
|
||||
comp := app.GetComponent(componentType)
|
||||
@@ -64,8 +76,7 @@ func (r *Reconciler) fetchWorkload(app *corev1alpha2.Application, componentType
|
||||
return nil, fmt.Errorf("cannot find the component %s in the application", componentType)
|
||||
}
|
||||
// get the workload given GVK and name
|
||||
workload, err := oamutil.GetObjectGivenGVKAndName(context.Background(), r, gvk, app.GetNamespace(),
|
||||
comp.Name)
|
||||
workload, err := oamutil.GetObjectGivenGVKAndName(ctx, r, gvk, app.GetNamespace(), comp.Name)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("failed to get workload %s with gvk %+v ", componentType, gvk))
|
||||
}
|
||||
+52
-14
@@ -3,6 +3,7 @@ package applicationdeployment
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/event"
|
||||
"github.com/crossplane/crossplane-runtime/pkg/logging"
|
||||
@@ -15,11 +16,15 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
corev1alpha2 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha2"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/common/rollout"
|
||||
controller "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2/application"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
)
|
||||
|
||||
const appDeployfinalizer = "finalizers.applicationdeployment.oam.dev"
|
||||
const appDeployFinalizer = "finalizers.applicationdeployment.oam.dev"
|
||||
const reconcileTimeOut = 10 * time.Second
|
||||
|
||||
// Reconciler reconciles an ApplicationDeployment object
|
||||
type Reconciler struct {
|
||||
@@ -29,13 +34,16 @@ type Reconciler struct {
|
||||
Scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
// Reconcile is the main logic of applicationdeployment controller
|
||||
// +kubebuilder:rbac:groups=core.oam.dev,resources=applicationdeployments,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=core.oam.dev,resources=applicationdeployments/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=core.oam.dev,resources=applicationconfigurations,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=core.oam.dev,resources=applications,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=core.oam.dev,resources=applications/status,verbs=get;update;patch
|
||||
|
||||
// Reconcile is the main logic of applicationdeployment controller
|
||||
func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
ctx := context.Background()
|
||||
var appDeploy corev1alpha2.ApplicationDeployment
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), reconcileTimeOut)
|
||||
defer cancel()
|
||||
if err := r.Get(ctx, req.NamespacedName, &appDeploy); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
klog.InfoS("application deployment does not exist", "appDeploy", klog.KRef(req.Namespace, req.Name))
|
||||
@@ -47,7 +55,8 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
r.handleFinalizer(&appDeploy)
|
||||
|
||||
// Get the target application
|
||||
var targetApp, sourceApp corev1alpha2.Application
|
||||
var targetApp corev1alpha2.Application
|
||||
var sourceApp *corev1alpha2.Application
|
||||
targetAppName := appDeploy.Spec.TargetApplicationName
|
||||
if err := r.Get(ctx, ktypes.NamespacedName{Namespace: req.Namespace, Name: targetAppName},
|
||||
&targetApp); err != nil {
|
||||
@@ -55,37 +64,66 @@ func (r *Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
||||
klog.KRef(req.Namespace, targetAppName))
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// Get the source application
|
||||
sourceAppName := appDeploy.Spec.SourceApplicationName
|
||||
if sourceAppName == nil {
|
||||
if sourceAppName == "" {
|
||||
klog.Info("source app fields not filled, we assume it is deployed for the first time")
|
||||
} else if err := r.Get(ctx, ktypes.NamespacedName{Namespace: req.Namespace, Name: *sourceAppName},
|
||||
&sourceApp); err != nil {
|
||||
} else if err := r.Get(ctx, ktypes.NamespacedName{Namespace: req.Namespace, Name: sourceAppName}, sourceApp); err != nil {
|
||||
klog.ErrorS(err, "cannot locate source application", "source application", klog.KRef(req.Namespace,
|
||||
*sourceAppName))
|
||||
sourceAppName))
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
// Get the kubernetes workloads to upgrade from the application
|
||||
targetWorkload, sourceWorkload, err := r.extractWorkload(appDeploy.Spec.ComponentList, &targetApp, &sourceApp)
|
||||
workloadType, workloadGVK, err := r.extractWorkloadTypeAndGVK(ctx,
|
||||
appDeploy.Spec.ComponentList, &targetApp, sourceApp)
|
||||
if err != nil {
|
||||
klog.Error(err, "cannot locate the workloads object")
|
||||
klog.ErrorS(err, "cannot extract the workloadType and GVK",
|
||||
"component list", appDeploy.Spec.ComponentList, "target app", klog.KObj(&targetApp))
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
targetWorkload, sourceWorkload, err := r.fetchWorkloads(ctx, &targetApp, sourceApp, workloadType, workloadGVK)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot fetch the workloads to upgrade", "workload Type", workloadType,
|
||||
"workload GVK", *workloadGVK, "target application", klog.KRef(req.Namespace, targetAppName),
|
||||
"source application", klog.KRef(req.Namespace, sourceAppName))
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
klog.InfoS("get the target workload we need to work on", "targetWorkload", klog.KObj(targetWorkload))
|
||||
|
||||
// check if the target application is still in rolling
|
||||
if _, exist := targetApp.GetAnnotations()[oam.AnnotationAppRollout]; exist {
|
||||
// adjust the target workload if it's still a template
|
||||
if err := r.adjustTargetApplicationTemplate(ctx, targetWorkload, &targetApp); err != nil {
|
||||
klog.ErrorS(err, "cannot adjust the target workload", "target workload", klog.KObj(targetWorkload))
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
// requeue it to process hopefully after the application controller takes over
|
||||
return ctrl.Result{RequeueAfter: 2 * application.RolloutReconcileWaitTime}, nil
|
||||
}
|
||||
|
||||
if sourceWorkload != nil {
|
||||
klog.InfoS("get the source workload we need to work on", "sourceWorkload", klog.KObj(sourceWorkload))
|
||||
}
|
||||
// TODO: pass these two object to the rollout plan
|
||||
|
||||
// reconcile the rollout part of the spec given the target and source workload
|
||||
err = rollout.ReconcileRolloutPlan(ctx, r, &appDeploy.Spec.RolloutPlan, targetWorkload, sourceWorkload)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "cannot reconcile the rollout plan", "rollout spec", appDeploy.Spec.RolloutPlan)
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *Reconciler) handleFinalizer(appDeploy *corev1alpha2.ApplicationDeployment) {
|
||||
if appDeploy.DeletionTimestamp.IsZero() {
|
||||
if !slice.ContainsString(appDeploy.Finalizers, appDeployfinalizer, nil) {
|
||||
if !slice.ContainsString(appDeploy.Finalizers, appDeployFinalizer, nil) {
|
||||
// TODO: add finalizer
|
||||
klog.Info("add finalizer")
|
||||
}
|
||||
} else if slice.ContainsString(appDeploy.Finalizers, appDeployfinalizer, nil) {
|
||||
} else if slice.ContainsString(appDeploy.Finalizers, appDeployFinalizer, nil) {
|
||||
// TODO: perform finalize
|
||||
klog.Info("perform clean up")
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
package workloads
|
||||
@@ -182,7 +182,7 @@ func FetchTraitDefinition(ctx context.Context, r client.Reader, dm discoverymapp
|
||||
return nil, err
|
||||
}
|
||||
// Fetch the corresponding traitDefinition CR
|
||||
traitDefinition, err := GetTraitDefinition(r, trName)
|
||||
traitDefinition, err := GetTraitDefinition(ctx, r, trName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -198,7 +198,7 @@ func FetchWorkloadDefinition(ctx context.Context, r client.Reader, dm discoverym
|
||||
return nil, err
|
||||
}
|
||||
// Fetch the corresponding workloadDefinition CR
|
||||
workloadDefinition, err := GetWorkloadDefinition(r, wldName)
|
||||
workloadDefinition, err := GetWorkloadDefinition(ctx, r, wldName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -214,18 +214,19 @@ func GenNamespacedDefinitionName(dn string) types.NamespacedName {
|
||||
}
|
||||
|
||||
// GetWorkloadDefinition Get WorkloadDefinition
|
||||
func GetWorkloadDefinition(cli client.Reader, workitemName string) (*v1alpha2.WorkloadDefinition, error) {
|
||||
func GetWorkloadDefinition(ctx context.Context, cli client.Reader,
|
||||
workitemName string) (*v1alpha2.WorkloadDefinition, error) {
|
||||
wd := new(v1alpha2.WorkloadDefinition)
|
||||
if err := cli.Get(context.Background(), GenNamespacedDefinitionName(workitemName), wd); err != nil {
|
||||
if err := cli.Get(ctx, GenNamespacedDefinitionName(workitemName), wd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return wd, nil
|
||||
}
|
||||
|
||||
// GetTraitDefinition Get TraitDefinition
|
||||
func GetTraitDefinition(cli client.Reader, traitName string) (*v1alpha2.TraitDefinition, error) {
|
||||
func GetTraitDefinition(ctx context.Context, cli client.Reader, traitName string) (*v1alpha2.TraitDefinition, error) {
|
||||
td := new(v1alpha2.TraitDefinition)
|
||||
if err := cli.Get(context.Background(), GenNamespacedDefinitionName(traitName), td); err != nil {
|
||||
if err := cli.Get(ctx, GenNamespacedDefinitionName(traitName), td); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return td, nil
|
||||
|
||||
@@ -38,7 +38,7 @@ func GetScopeGVK(cli client.Client, dm discoverymapper.DiscoveryMapper,
|
||||
func LoadTemplate(cli client.Reader, key string, kd types.CapType) (*Template, error) {
|
||||
switch kd {
|
||||
case types.TypeWorkload:
|
||||
wd, err := GetWorkloadDefinition(cli, key)
|
||||
wd, err := GetWorkloadDefinition(context.TODO(), cli, key)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "LoadTemplate [%s] ", key)
|
||||
}
|
||||
@@ -57,7 +57,7 @@ func LoadTemplate(cli client.Reader, key string, kd types.CapType) (*Template, e
|
||||
return tmpl, nil
|
||||
|
||||
case types.TypeTrait:
|
||||
td, err := GetTraitDefinition(cli, key)
|
||||
td, err := GetTraitDefinition(context.TODO(), cli, key)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "LoadTemplate [%s] ", key)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func FindCommonComponent(targetApp, sourceApp *v1alpha2.Application) []string {
|
||||
return commonComponents
|
||||
}
|
||||
// find the common components in both the source and target application
|
||||
// write an O(N) algorithm just for fun, totally doesn't worth the extra effort
|
||||
// write an O(N) algorithm just for fun, totally doesn't worth the extra space
|
||||
targetComponents := make(map[string]bool)
|
||||
for _, comp := range targetApp.Spec.Components {
|
||||
targetComponents[comp.WorkloadType] = true
|
||||
@@ -26,5 +26,4 @@ func FindCommonComponent(targetApp, sourceApp *v1alpha2.Application) []string {
|
||||
}
|
||||
}
|
||||
return commonComponents
|
||||
|
||||
}
|
||||
|
||||
@@ -39,12 +39,12 @@ func (h *ValidatingHandler) ValidateCreate(appDeploy *v1alpha2.ApplicationDeploy
|
||||
return allErrs
|
||||
}
|
||||
sourceAppName := appDeploy.Spec.SourceApplicationName
|
||||
if sourceAppName != nil {
|
||||
if err := h.Get(context.Background(), ktypes.NamespacedName{Namespace: appDeploy.Namespace, Name: *sourceAppName},
|
||||
if sourceAppName != "" {
|
||||
if err := h.Get(context.Background(), ktypes.NamespacedName{Namespace: appDeploy.Namespace, Name: sourceAppName},
|
||||
&sourceApp); err != nil {
|
||||
klog.ErrorS(err, "cannot locate source application", "source application",
|
||||
klog.KRef(appDeploy.Namespace, *sourceAppName))
|
||||
allErrs = append(allErrs, field.NotFound(fldPath.Child("sourceApplicationName"), *sourceAppName))
|
||||
klog.KRef(appDeploy.Namespace, sourceAppName))
|
||||
allErrs = append(allErrs, field.NotFound(fldPath.Child("sourceApplicationName"), sourceAppName))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user