Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(operator): Add information about current phase in workloadinstances and appversions #200

Merged
merged 3 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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-Evaluation", ShortName: "AppPreEvaluation"}
PhaseAppPostEvaluation = KeptnPhaseType{LongName: "App Post-Evaluation", ShortName: "AppPostEvaluation"}
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