Skip to content

Commit

Permalink
feat(operator): Add information about current phase in workloadinstan…
Browse files Browse the repository at this point in the history
…ces and appversions (#200)
  • Loading branch information
thschue authored Oct 20, 2022
1 parent 0489374 commit 55fa4e9
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 17 deletions.
1 change: 1 addition & 0 deletions operator/api/v1alpha1/common/phases.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ var (
PhaseAppPreEvaluation = KeptnPhaseType{LongName: "App Pre-Deployment Evaluations", ShortName: "AppPreDeployEvaluations"}
PhaseAppPostEvaluation = KeptnPhaseType{LongName: "App Post-Deployment Evaluations", ShortName: "AppPostDeployEvaluations"}
PhaseAppDeployment = KeptnPhaseType{LongName: "App Deployment", ShortName: "AppDeploy"}
PhaseCompleted = KeptnPhaseType{LongName: "Completed", ShortName: "Completed"}
)
6 changes: 3 additions & 3 deletions operator/api/v1alpha1/keptnappversion_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ type KeptnAppVersionStatus struct {
// +kubebuilder:default:=Pending
PostDeploymentEvaluationStatus common.KeptnState `json:"postDeploymentEvaluationStatus,omitempty"`
// +kubebuilder:default:=Pending
WorkloadOverallStatus common.KeptnState `json:"workloadOverallStatus,omitempty"`
WorkloadStatus []WorkloadStatus `json:"workloadStatus,omitempty"`

WorkloadOverallStatus common.KeptnState `json:"workloadOverallStatus,omitempty"`
WorkloadStatus []WorkloadStatus `json:"workloadStatus,omitempty"`
CurrentPhase string `json:"currentPhase,omitempty"`
PreDeploymentTaskStatus []TaskStatus `json:"preDeploymentTaskStatus,omitempty"`
PostDeploymentTaskStatus []TaskStatus `json:"postDeploymentTaskStatus,omitempty"`
PreDeploymentEvaluationTaskStatus []EvaluationStatus `json:"preDeploymentEvaluationTaskStatus,omitempty"`
Expand Down
1 change: 1 addition & 0 deletions operator/api/v1alpha1/keptnworkloadinstance_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type KeptnWorkloadInstanceStatus struct {
PostDeploymentEvaluationTaskStatus []EvaluationStatus `json:"postDeploymentEvaluationTaskStatus,omitempty"`
StartTime metav1.Time `json:"startTime,omitempty"`
EndTime metav1.Time `json:"endTime,omitempty"`
CurrentPhase string `json:"currentPhase,omitempty"`
}

type TaskStatus struct {
Expand Down
21 changes: 14 additions & 7 deletions operator/controllers/keptnappversion/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,23 +99,23 @@ func (r *KeptnAppVersionReconciler) Reconcile(ctx context.Context, req ctrl.Requ
reconcilePreDep := func() (common.KeptnState, error) {
return r.reconcilePrePostDeployment(ctx, appVersion, common.PreDeploymentCheckType)
}
return r.handlePhase(appVersion, phase, span, appVersion.IsPreDeploymentFailed, reconcilePreDep)
return r.handlePhase(ctx, appVersion, phase, span, appVersion.IsPreDeploymentFailed, reconcilePreDep)
}

phase = common.PhaseAppPreEvaluation
if !appVersion.IsPreDeploymentEvaluationSucceeded() {
reconcilePreEval := func() (common.KeptnState, error) {
return r.reconcilePrePostEvaluation(ctx, appVersion, common.PreDeploymentEvaluationCheckType)
}
return r.handlePhase(appVersion, phase, span, appVersion.IsPreDeploymentEvaluationFailed, reconcilePreEval)
return r.handlePhase(ctx, appVersion, phase, span, appVersion.IsPreDeploymentEvaluationFailed, reconcilePreEval)
}

phase = common.PhaseAppDeployment
if !appVersion.AreWorkloadsSucceeded() {
reconcileAppDep := func() (common.KeptnState, error) {
return r.reconcileWorkloads(ctx, appVersion)
}
return r.handlePhase(appVersion, phase, span, appVersion.AreWorkloadsFailed, reconcileAppDep)
return r.handlePhase(ctx, appVersion, phase, span, appVersion.AreWorkloadsFailed, reconcileAppDep)

}

Expand All @@ -124,15 +124,15 @@ func (r *KeptnAppVersionReconciler) Reconcile(ctx context.Context, req ctrl.Requ
reconcilePostDep := func() (common.KeptnState, error) {
return r.reconcilePrePostDeployment(ctx, appVersion, common.PostDeploymentCheckType)
}
return r.handlePhase(appVersion, phase, span, appVersion.IsPostDeploymentFailed, reconcilePostDep)
return r.handlePhase(ctx, appVersion, phase, span, appVersion.IsPostDeploymentFailed, reconcilePostDep)
}

phase = common.PhaseAppPostEvaluation
if !appVersion.IsPostDeploymentEvaluationCompleted() {
reconcilePostEval := func() (common.KeptnState, error) {
return r.reconcilePrePostEvaluation(ctx, appVersion, common.PostDeploymentEvaluationCheckType)
}
return r.handlePhase(appVersion, phase, span, appVersion.IsPostDeploymentEvaluationFailed, reconcilePostEval)
return r.handlePhase(ctx, appVersion, phase, span, appVersion.IsPostDeploymentEvaluationFailed, reconcilePostEval)
}

r.recordEvent(phase, "Normal", appVersion, "Finished", "is finished")
Expand All @@ -147,6 +147,7 @@ func (r *KeptnAppVersionReconciler) Reconcile(ctx context.Context, req ctrl.Requ
if !appVersion.IsEndTimeSet() {
// metrics: decrement active app counter
r.Meters.AppActive.Add(ctx, -1, appVersion.GetActiveMetricsAttributes()...)
appVersion.Status.CurrentPhase = common.PhaseCompleted.ShortName
appVersion.SetEndTime()
}

Expand Down Expand Up @@ -180,9 +181,10 @@ func (r *KeptnAppVersionReconciler) recordEvent(phase common.KeptnPhaseType, eve
r.Recorder.Event(appVersion, eventType, fmt.Sprintf("%s%s", phase.ShortName, shortReason), fmt.Sprintf("%s %s / Namespace: %s, Name: %s, Version: %s ", phase.LongName, longReason, appVersion.Namespace, appVersion.Name, appVersion.Spec.Version))
}

func (r *KeptnAppVersionReconciler) handlePhase(appVersion *klcv1alpha1.KeptnAppVersion, phase common.KeptnPhaseType, span trace.Span, phaseFailed func() bool, reconcilePhase func() (common.KeptnState, error)) (ctrl.Result, error) {

func (r *KeptnAppVersionReconciler) handlePhase(ctx context.Context, appVersion *klcv1alpha1.KeptnAppVersion, phase common.KeptnPhaseType, span trace.Span, phaseFailed func() bool, reconcilePhase func() (common.KeptnState, error)) (ctrl.Result, error) {
r.Log.Info(phase.LongName + " not finished")
oldPhase := appVersion.Status.CurrentPhase
appVersion.Status.CurrentPhase = phase.ShortName
if phaseFailed() { //TODO eventually we should decide whether a task returns FAILED, currently we never have this status set
r.recordEvent(phase, "Warning", appVersion, "Failed", "has failed")
return ctrl.Result{Requeue: true, RequeueAfter: 60 * time.Second}, nil
Expand All @@ -198,5 +200,10 @@ func (r *KeptnAppVersionReconciler) handlePhase(appVersion *klcv1alpha1.KeptnApp
} else {
r.recordEvent(phase, "Warning", appVersion, "NotFinished", "has not finished")
}
if oldPhase != appVersion.Status.CurrentPhase {
if err := r.Status().Update(ctx, appVersion); err != nil {
r.Log.Error(err, "could not update status")
}
}
return ctrl.Result{Requeue: true, RequeueAfter: 5 * time.Second}, nil
}
21 changes: 14 additions & 7 deletions operator/controllers/keptnworkloadinstance/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (r *KeptnWorkloadInstanceReconciler) Reconcile(ctx context.Context, req ctr
reconcilePre := func() (common.KeptnState, error) {
return r.reconcilePrePostDeployment(ctx, workloadInstance, common.PreDeploymentCheckType)
}
return r.handlePhase(workloadInstance, phase, span, workloadInstance.IsPreDeploymentFailed, reconcilePre)
return r.handlePhase(ctx, workloadInstance, phase, span, workloadInstance.IsPreDeploymentFailed, reconcilePre)
}

//Wait for pre-evaluation checks of Workload
Expand All @@ -141,7 +141,7 @@ func (r *KeptnWorkloadInstanceReconciler) Reconcile(ctx context.Context, req ctr
reconcilePreEval := func() (common.KeptnState, error) {
return r.reconcilePrePostEvaluation(ctx, workloadInstance, common.PreDeploymentEvaluationCheckType)
}
return r.handlePhase(workloadInstance, phase, span, workloadInstance.IsPreDeploymentEvaluationFailed, reconcilePreEval)
return r.handlePhase(ctx, workloadInstance, phase, span, workloadInstance.IsPreDeploymentEvaluationFailed, reconcilePreEval)
}

//Wait for deployment of Workload
Expand All @@ -150,7 +150,7 @@ func (r *KeptnWorkloadInstanceReconciler) Reconcile(ctx context.Context, req ctr
reconcileWorkloadInstance := func() (common.KeptnState, error) {
return r.reconcileDeployment(ctx, workloadInstance)
}
return r.handlePhase(workloadInstance, phase, span, workloadInstance.IsDeploymentFailed, reconcileWorkloadInstance)
return r.handlePhase(ctx, workloadInstance, phase, span, workloadInstance.IsDeploymentFailed, reconcileWorkloadInstance)
}

//Wait for post-deployment checks of Workload
Expand All @@ -159,7 +159,7 @@ func (r *KeptnWorkloadInstanceReconciler) Reconcile(ctx context.Context, req ctr
reconcilePostDeployment := func() (common.KeptnState, error) {
return r.reconcilePrePostDeployment(ctx, workloadInstance, common.PostDeploymentCheckType)
}
return r.handlePhase(workloadInstance, phase, span, workloadInstance.IsPostDeploymentFailed, reconcilePostDeployment)
return r.handlePhase(ctx, workloadInstance, phase, span, workloadInstance.IsPostDeploymentFailed, reconcilePostDeployment)
}

//Wait for post-evaluation checks of Workload
Expand All @@ -168,13 +168,14 @@ func (r *KeptnWorkloadInstanceReconciler) Reconcile(ctx context.Context, req ctr
reconcilePostEval := func() (common.KeptnState, error) {
return r.reconcilePrePostEvaluation(ctx, workloadInstance, common.PostDeploymentEvaluationCheckType)
}
return r.handlePhase(workloadInstance, phase, span, workloadInstance.IsPostDeploymentEvaluationFailed, reconcilePostEval)
return r.handlePhase(ctx, workloadInstance, phase, span, workloadInstance.IsPostDeploymentEvaluationFailed, reconcilePostEval)
}

// WorkloadInstance is completed at this place
if !workloadInstance.IsEndTimeSet() {
// metrics: decrement active deployment counter
r.Meters.DeploymentActive.Add(ctx, -1, workloadInstance.GetActiveMetricsAttributes()...)
workloadInstance.Status.CurrentPhase = common.PhaseCompleted.ShortName
workloadInstance.SetEndTime()
}

Expand All @@ -199,9 +200,10 @@ func (r *KeptnWorkloadInstanceReconciler) Reconcile(ctx context.Context, req ctr
return ctrl.Result{}, nil
}

func (r *KeptnWorkloadInstanceReconciler) handlePhase(workloadInstance *klcv1alpha1.KeptnWorkloadInstance, phase common.KeptnPhaseType, span trace.Span, phaseFailed func() bool, reconcilePhase func() (common.KeptnState, error)) (ctrl.Result, error) {

func (r *KeptnWorkloadInstanceReconciler) handlePhase(ctx context.Context, workloadInstance *klcv1alpha1.KeptnWorkloadInstance, phase common.KeptnPhaseType, span trace.Span, phaseFailed func() bool, reconcilePhase func() (common.KeptnState, error)) (ctrl.Result, error) {
r.Log.Info(phase.LongName + " not finished")
oldPhase := workloadInstance.Status.CurrentPhase
workloadInstance.Status.CurrentPhase = phase.ShortName
if phaseFailed() { //TODO eventually we should decide whether a task returns FAILED, currently we never have this status set
r.recordEvent(phase, "Warning", workloadInstance, "Failed", "has failed")
return ctrl.Result{Requeue: true, RequeueAfter: 60 * time.Second}, nil
Expand All @@ -217,6 +219,11 @@ func (r *KeptnWorkloadInstanceReconciler) handlePhase(workloadInstance *klcv1alp
} else {
r.recordEvent(phase, "Warning", workloadInstance, "NotFinished", "has not finished")
}
if oldPhase != workloadInstance.Status.CurrentPhase {
if err := r.Status().Update(ctx, workloadInstance); err != nil {
r.Log.Error(err, "could not update status")
}
}
return ctrl.Result{Requeue: true, RequeueAfter: 5 * time.Second}, nil
}

Expand Down

0 comments on commit 55fa4e9

Please sign in to comment.