diff --git a/Makefile b/Makefile index 5736cbde45..c667f5f2f6 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ integration-test: chainsaw test --test-dir ./test/chainsaw/integration/ chainsaw test --test-dir ./test/chainsaw/testanalysis/ chainsaw test --test-dir ./test/chainsaw/testcertificate/ + chainsaw test --test-dir ./test/chainsaw/non-blocking-deployment/ .PHONY: integration-test-local #these tests should run on a real cluster! integration-test-local: @@ -41,6 +42,7 @@ integration-test-local: chainsaw test --test-dir ./test/chainsaw/testmetrics/ --config ./.chainsaw-local.yaml chainsaw test --test-dir ./test/chainsaw/testanalysis/ --config ./.chainsaw-local.yaml chainsaw test --test-dir ./test/chainsaw/testcertificate/ --config ./.chainsaw-local.yaml + chainsaw test --test-dir ./test/chainsaw/non-blocking-deployment/ --config ./.chainsaw-local.yaml .PHONY: integration-test-scheduling-gates #these tests should run on a real cluster! integration-test-scheduling-gates: diff --git a/lifecycle-operator/apis/lifecycle/v1beta1/common/common.go b/lifecycle-operator/apis/lifecycle/v1beta1/common/common.go index e41e52e115..a3d765e6e0 100644 --- a/lifecycle-operator/apis/lifecycle/v1beta1/common/common.go +++ b/lifecycle-operator/apis/lifecycle/v1beta1/common/common.go @@ -55,11 +55,11 @@ const ( StateUnknown KeptnState = "Unknown" StatePending KeptnState = "Pending" StateDeprecated KeptnState = "Deprecated" - // Deprecated: Use StateDeprecated instead. Should only be used in checks for backwards compatibility reasons + StateWarning KeptnState = "Warning" ) func (k KeptnState) IsCompleted() bool { - return k == StateSucceeded || k == StateFailed || k == StateDeprecated + return k == StateSucceeded || k == StateFailed || k == StateDeprecated || k == StateWarning } func (k KeptnState) IsSucceeded() bool { @@ -78,6 +78,10 @@ func (k KeptnState) IsPending() bool { return k == StatePending } +func (k KeptnState) IsWarning() bool { + return k == StateWarning +} + type StatusSummary struct { Total int Progressing int @@ -126,6 +130,14 @@ func GetOverallState(s StatusSummary) KeptnState { return StateSucceeded } +func GetOverallStateBlockedDeployment(s StatusSummary, blockedDeployment bool) KeptnState { + state := GetOverallState(s) + if !blockedDeployment && state == StateFailed { + return StateWarning + } + return state +} + func TruncateString(s string, max int) string { if len(s) > max { return s[:max] diff --git a/lifecycle-operator/apis/lifecycle/v1beta1/common/common_test.go b/lifecycle-operator/apis/lifecycle/v1beta1/common/common_test.go index ea05466ed7..02cea6084e 100644 --- a/lifecycle-operator/apis/lifecycle/v1beta1/common/common_test.go +++ b/lifecycle-operator/apis/lifecycle/v1beta1/common/common_test.go @@ -39,6 +39,31 @@ func TestKeptnState_IsCompleted(t *testing.T) { } } +func TestKeptnState_IsWarning(t *testing.T) { + tests := []struct { + State KeptnState + Want bool + }{ + { + State: StateSucceeded, + Want: false, + }, + { + State: StateFailed, + Want: false, + }, + { + State: StateWarning, + Want: true, + }, + } + for _, tt := range tests { + t.Run("", func(t *testing.T) { + require.Equal(t, tt.State.IsWarning(), tt.Want) + }) + } +} + func TestKeptnState_IsSucceeded(t *testing.T) { tests := []struct { State KeptnState @@ -240,6 +265,45 @@ func Test_GeOverallState(t *testing.T) { } } +func Test_GeOverallStateBlockedDeployment(t *testing.T) { + tests := []struct { + Name string + Summary StatusSummary + Block bool + Want KeptnState + }{ + { + Name: "failed blocking", + Summary: StatusSummary{0, 0, 1, 0, 0, 0, 0}, + Block: true, + Want: StateFailed, + }, + { + Name: "succeeded blocking", + Summary: StatusSummary{1, 0, 0, 1, 0, 0, 0}, + Block: true, + Want: StateSucceeded, + }, + { + Name: "failed non-blocking", + Summary: StatusSummary{0, 0, 1, 0, 0, 0, 0}, + Block: false, + Want: StateWarning, + }, + { + Name: "succeeded non-blocking", + Summary: StatusSummary{1, 0, 0, 1, 0, 0, 0}, + Block: false, + Want: StateSucceeded, + }, + } + for _, tt := range tests { + t.Run(tt.Name, func(t *testing.T) { + require.Equal(t, GetOverallStateBlockedDeployment(tt.Summary, tt.Block), tt.Want) + }) + } +} + func Test_TruncateString(t *testing.T) { tests := []struct { Input string diff --git a/lifecycle-operator/apis/lifecycle/v1beta1/keptnappversion_types.go b/lifecycle-operator/apis/lifecycle/v1beta1/keptnappversion_types.go index 70e2632d8d..de533ff6ee 100644 --- a/lifecycle-operator/apis/lifecycle/v1beta1/keptnappversion_types.go +++ b/lifecycle-operator/apis/lifecycle/v1beta1/keptnappversion_types.go @@ -183,16 +183,22 @@ func (a KeptnAppVersion) IsPreDeploymentEvaluationCompleted() bool { return a.Status.PreDeploymentEvaluationStatus.IsCompleted() } -func (a KeptnAppVersion) IsPreDeploymentSucceeded() bool { - return a.Status.PreDeploymentStatus.IsSucceeded() +func (a KeptnAppVersion) IsPreDeploymentSucceeded(isBlocking bool) bool { + if isBlocking { + return a.Status.PreDeploymentStatus.IsSucceeded() + } + return a.Status.PreDeploymentStatus.IsSucceeded() || a.Status.PreDeploymentStatus.IsWarning() } func (a KeptnAppVersion) IsPreDeploymentFailed() bool { return a.Status.PreDeploymentStatus.IsFailed() } -func (a KeptnAppVersion) IsPreDeploymentEvaluationSucceeded() bool { - return a.Status.PreDeploymentEvaluationStatus.IsSucceeded() +func (a KeptnAppVersion) IsPreDeploymentEvaluationSucceeded(isBlocking bool) bool { + if isBlocking { + return a.Status.PreDeploymentEvaluationStatus.IsSucceeded() + } + return a.Status.PreDeploymentEvaluationStatus.IsSucceeded() || a.Status.PreDeploymentEvaluationStatus.IsWarning() } func (a KeptnAppVersion) IsPreDeploymentEvaluationFailed() bool { @@ -219,16 +225,22 @@ func (a KeptnAppVersion) IsPromotionFailed() bool { return a.Status.PromotionStatus.IsFailed() } -func (a KeptnAppVersion) IsPostDeploymentEvaluationSucceeded() bool { - return a.Status.PostDeploymentEvaluationStatus.IsSucceeded() +func (a KeptnAppVersion) IsPostDeploymentEvaluationSucceeded(isBlocking bool) bool { + if isBlocking { + return a.Status.PostDeploymentEvaluationStatus.IsSucceeded() + } + return a.Status.PostDeploymentEvaluationStatus.IsSucceeded() || a.Status.PostDeploymentEvaluationStatus.IsWarning() } func (a KeptnAppVersion) IsPostDeploymentEvaluationFailed() bool { return a.Status.PostDeploymentEvaluationStatus.IsFailed() } -func (a KeptnAppVersion) IsPostDeploymentSucceeded() bool { - return a.Status.PostDeploymentStatus.IsSucceeded() +func (a KeptnAppVersion) IsPostDeploymentSucceeded(isBlocking bool) bool { + if isBlocking { + return a.Status.PostDeploymentStatus.IsSucceeded() + } + return a.Status.PostDeploymentStatus.IsSucceeded() || a.Status.PostDeploymentStatus.IsWarning() } func (a KeptnAppVersion) IsPromotionSucceeded() bool { diff --git a/lifecycle-operator/apis/lifecycle/v1beta1/keptnappversion_types_test.go b/lifecycle-operator/apis/lifecycle/v1beta1/keptnappversion_types_test.go index cbb8795201..4c9e642c53 100644 --- a/lifecycle-operator/apis/lifecycle/v1beta1/keptnappversion_types_test.go +++ b/lifecycle-operator/apis/lifecycle/v1beta1/keptnappversion_types_test.go @@ -8,13 +8,12 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/propagation" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestKeptnAppVersion(t *testing.T) { app := &KeptnAppVersion{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "app", Namespace: "namespace", }, @@ -83,19 +82,19 @@ func TestKeptnAppVersion(t *testing.T) { } require.True(t, app.IsPreDeploymentCompleted()) - require.False(t, app.IsPreDeploymentSucceeded()) + require.False(t, app.IsPreDeploymentSucceeded(true)) require.True(t, app.IsPreDeploymentFailed()) require.True(t, app.IsPreDeploymentEvaluationCompleted()) - require.False(t, app.IsPreDeploymentEvaluationSucceeded()) + require.False(t, app.IsPreDeploymentEvaluationSucceeded(true)) require.True(t, app.IsPreDeploymentEvaluationFailed()) require.True(t, app.IsPostDeploymentCompleted()) - require.False(t, app.IsPostDeploymentSucceeded()) + require.False(t, app.IsPostDeploymentSucceeded(true)) require.True(t, app.IsPostDeploymentFailed()) require.True(t, app.IsPostDeploymentEvaluationCompleted()) - require.False(t, app.IsPostDeploymentEvaluationSucceeded()) + require.False(t, app.IsPostDeploymentEvaluationSucceeded(true)) require.True(t, app.IsPostDeploymentEvaluationFailed()) require.True(t, app.IsPromotionCompleted()) @@ -106,6 +105,28 @@ func TestKeptnAppVersion(t *testing.T) { require.False(t, app.AreWorkloadsSucceeded()) require.True(t, app.AreWorkloadsFailed()) + app.Status.PreDeploymentStatus = common.StateWarning + app.Status.PreDeploymentEvaluationStatus = common.StateWarning + app.Status.PostDeploymentStatus = common.StateWarning + app.Status.PostDeploymentEvaluationStatus = common.StateWarning + + require.False(t, app.IsPreDeploymentSucceeded(true)) + require.True(t, app.IsPreDeploymentSucceeded(false)) + + require.False(t, app.IsPreDeploymentEvaluationSucceeded(true)) + require.True(t, app.IsPreDeploymentEvaluationSucceeded(false)) + + require.False(t, app.IsPostDeploymentSucceeded(true)) + require.True(t, app.IsPostDeploymentSucceeded(false)) + + require.False(t, app.IsPostDeploymentEvaluationSucceeded(true)) + require.True(t, app.IsPostDeploymentEvaluationSucceeded(false)) + + app.Status.PreDeploymentStatus = common.StateFailed + app.Status.PreDeploymentEvaluationStatus = common.StateFailed + app.Status.PostDeploymentStatus = common.StateFailed + app.Status.PostDeploymentEvaluationStatus = common.StateFailed + require.False(t, app.IsEndTimeSet()) require.False(t, app.IsStartTimeSet()) @@ -257,7 +278,7 @@ func TestKeptnAppVersion(t *testing.T) { AppName: app.GetParentName(), EvaluationDefinition: "eval-def", Type: common.PostDeploymentCheckType, - RetryInterval: metav1.Duration{ + RetryInterval: v1.Duration{ Duration: 5 * time.Second, }, }, evaluation.Spec) @@ -503,7 +524,7 @@ func TestKeptnAppVersionList(t *testing.T) { list := KeptnAppVersionList{ Items: []KeptnAppVersion{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "obj1", }, Status: KeptnAppVersionStatus{ @@ -511,7 +532,7 @@ func TestKeptnAppVersionList(t *testing.T) { }, }, { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "obj2", }, Status: KeptnAppVersionStatus{ diff --git a/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkload_types_test.go b/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkload_types_test.go index 9470b6f89d..6bb8a01262 100644 --- a/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkload_types_test.go +++ b/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkload_types_test.go @@ -6,13 +6,12 @@ import ( "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1/common" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestKeptnWorkload(t *testing.T) { workload := &KeptnWorkload{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "workload", Namespace: "namespace", }, diff --git a/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkloadversion_types.go b/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkloadversion_types.go index 56a8c99337..248966389c 100644 --- a/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkloadversion_types.go +++ b/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkloadversion_types.go @@ -177,16 +177,22 @@ func (w KeptnWorkloadVersion) IsPreDeploymentEvaluationCompleted() bool { return w.Status.PreDeploymentEvaluationStatus.IsCompleted() } -func (w KeptnWorkloadVersion) IsPreDeploymentSucceeded() bool { - return w.Status.PreDeploymentStatus.IsSucceeded() +func (w KeptnWorkloadVersion) IsPreDeploymentSucceeded(isBlocking bool) bool { + if isBlocking { + return w.Status.PreDeploymentStatus.IsSucceeded() + } + return w.Status.PreDeploymentStatus.IsSucceeded() || w.Status.PreDeploymentStatus.IsWarning() } func (w KeptnWorkloadVersion) IsPreDeploymentFailed() bool { return w.Status.PreDeploymentStatus.IsFailed() } -func (w KeptnWorkloadVersion) IsPreDeploymentEvaluationSucceeded() bool { - return w.Status.PreDeploymentEvaluationStatus.IsSucceeded() +func (w KeptnWorkloadVersion) IsPreDeploymentEvaluationSucceeded(isBlocking bool) bool { + if isBlocking { + return w.Status.PreDeploymentEvaluationStatus.IsSucceeded() + } + return w.Status.PreDeploymentEvaluationStatus.IsSucceeded() || w.Status.PreDeploymentEvaluationStatus.IsWarning() } func (w KeptnWorkloadVersion) IsPreDeploymentEvaluationFailed() bool { @@ -201,16 +207,22 @@ func (w KeptnWorkloadVersion) IsPostDeploymentEvaluationCompleted() bool { return w.Status.PostDeploymentEvaluationStatus.IsCompleted() } -func (w KeptnWorkloadVersion) IsPostDeploymentSucceeded() bool { - return w.Status.PostDeploymentStatus.IsSucceeded() +func (w KeptnWorkloadVersion) IsPostDeploymentSucceeded(isBlocking bool) bool { + if isBlocking { + return w.Status.PostDeploymentStatus.IsSucceeded() + } + return w.Status.PostDeploymentStatus.IsSucceeded() || w.Status.PostDeploymentStatus.IsWarning() } func (w KeptnWorkloadVersion) IsPostDeploymentFailed() bool { return w.Status.PostDeploymentStatus.IsFailed() } -func (w KeptnWorkloadVersion) IsPostDeploymentEvaluationSucceeded() bool { - return w.Status.PostDeploymentEvaluationStatus.IsSucceeded() +func (w KeptnWorkloadVersion) IsPostDeploymentEvaluationSucceeded(isBlocking bool) bool { + if isBlocking { + return w.Status.PostDeploymentEvaluationStatus.IsSucceeded() + } + return w.Status.PostDeploymentEvaluationStatus.IsSucceeded() || w.Status.PostDeploymentEvaluationStatus.IsWarning() } func (w KeptnWorkloadVersion) IsPostDeploymentEvaluationFailed() bool { diff --git a/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkloadversion_types_test.go b/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkloadversion_types_test.go index 715af0f2b5..223d92d13d 100644 --- a/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkloadversion_types_test.go +++ b/lifecycle-operator/apis/lifecycle/v1beta1/keptnworkloadversion_types_test.go @@ -8,13 +8,12 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/propagation" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestKeptnWorkloadVersion(t *testing.T) { workload := &KeptnWorkloadVersion{ - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "workload", Namespace: "namespace", }, @@ -71,25 +70,47 @@ func TestKeptnWorkloadVersion(t *testing.T) { } require.True(t, workload.IsPreDeploymentCompleted()) - require.False(t, workload.IsPreDeploymentSucceeded()) + require.False(t, workload.IsPreDeploymentSucceeded(true)) require.True(t, workload.IsPreDeploymentFailed()) require.True(t, workload.IsPreDeploymentEvaluationCompleted()) - require.False(t, workload.IsPreDeploymentEvaluationSucceeded()) + require.False(t, workload.IsPreDeploymentEvaluationSucceeded(true)) require.True(t, workload.IsPreDeploymentEvaluationFailed()) require.True(t, workload.IsPostDeploymentCompleted()) - require.False(t, workload.IsPostDeploymentSucceeded()) + require.False(t, workload.IsPostDeploymentSucceeded(true)) require.True(t, workload.IsPostDeploymentFailed()) require.True(t, workload.IsPostDeploymentEvaluationCompleted()) - require.False(t, workload.IsPostDeploymentEvaluationSucceeded()) + require.False(t, workload.IsPostDeploymentEvaluationSucceeded(true)) require.True(t, workload.IsPostDeploymentEvaluationFailed()) require.True(t, workload.IsDeploymentCompleted()) require.False(t, workload.IsDeploymentSucceeded()) require.True(t, workload.IsDeploymentFailed()) + workload.Status.PreDeploymentStatus = common.StateWarning + workload.Status.PreDeploymentEvaluationStatus = common.StateWarning + workload.Status.PostDeploymentStatus = common.StateWarning + workload.Status.PostDeploymentEvaluationStatus = common.StateWarning + + require.False(t, workload.IsPreDeploymentSucceeded(true)) + require.True(t, workload.IsPreDeploymentSucceeded(false)) + + require.False(t, workload.IsPreDeploymentEvaluationSucceeded(true)) + require.True(t, workload.IsPreDeploymentEvaluationSucceeded(false)) + + require.False(t, workload.IsPostDeploymentSucceeded(true)) + require.True(t, workload.IsPostDeploymentSucceeded(false)) + + require.False(t, workload.IsPostDeploymentEvaluationSucceeded(true)) + require.True(t, workload.IsPostDeploymentEvaluationSucceeded(false)) + + workload.Status.PreDeploymentStatus = common.StateFailed + workload.Status.PreDeploymentEvaluationStatus = common.StateFailed + workload.Status.PostDeploymentStatus = common.StateFailed + workload.Status.PostDeploymentEvaluationStatus = common.StateFailed + require.False(t, workload.IsEndTimeSet()) require.False(t, workload.IsStartTimeSet()) @@ -237,7 +258,7 @@ func TestKeptnWorkloadVersion(t *testing.T) { Workload: workload.GetParentName(), EvaluationDefinition: "eval-def", Type: common.PostDeploymentCheckType, - RetryInterval: metav1.Duration{ + RetryInterval: v1.Duration{ Duration: 5 * time.Second, }, }, evaluation.Spec) @@ -438,12 +459,12 @@ func TestKeptnWorkloadVersionList(t *testing.T) { list := KeptnWorkloadVersionList{ Items: []KeptnWorkloadVersion{ { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "obj1", }, }, { - ObjectMeta: metav1.ObjectMeta{ + ObjectMeta: v1.ObjectMeta{ Name: "obj2", }, }, diff --git a/lifecycle-operator/controllers/lifecycle/keptnappversion/controller.go b/lifecycle-operator/controllers/lifecycle/keptnappversion/controller.go index 7dd7e3d334..297d61f10d 100644 --- a/lifecycle-operator/controllers/lifecycle/keptnappversion/controller.go +++ b/lifecycle-operator/controllers/lifecycle/keptnappversion/controller.go @@ -25,6 +25,7 @@ import ( klcv1beta1 "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1" apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1/common" controllercommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common" + "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/config" appcontext "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/context" "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/evaluation" "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/eventsender" @@ -60,6 +61,7 @@ type KeptnAppVersionReconciler struct { EvaluationHandler evaluation.IEvaluationHandler PhaseHandler phase.IHandler PromotionTasksEnabled bool + Config config.IConfig } // +kubebuilder:rbac:groups=lifecycle.keptn.sh,resources=keptnappversions,verbs=get;list;watch;create;update;patch;delete @@ -113,7 +115,7 @@ func (r *KeptnAppVersionReconciler) Reconcile(ctx context.Context, req ctrl.Requ spanAppTrace.AddEvent("App Version Pre-Deployment Tasks started", trace.WithTimestamp(time.Now())) } - if !appVersion.IsPreDeploymentSucceeded() { + if !appVersion.IsPreDeploymentSucceeded(r.Config.GetBlockDeployment()) { reconcilePreDep := func(phaseCtx context.Context) (apicommon.KeptnState, error) { return r.reconcilePhase(ctx, phaseCtx, appVersion, apicommon.PreDeploymentCheckType) } @@ -124,7 +126,7 @@ func (r *KeptnAppVersionReconciler) Reconcile(ctx context.Context, req ctrl.Requ } currentPhase = apicommon.PhaseAppPreEvaluation - if !appVersion.IsPreDeploymentEvaluationSucceeded() { + if !appVersion.IsPreDeploymentEvaluationSucceeded(r.Config.GetBlockDeployment()) { reconcilePreEval := func(phaseCtx context.Context) (apicommon.KeptnState, error) { return r.reconcilePrePostEvaluation(ctx, phaseCtx, appVersion, apicommon.PreDeploymentEvaluationCheckType) } @@ -146,7 +148,7 @@ func (r *KeptnAppVersionReconciler) Reconcile(ctx context.Context, req ctrl.Requ } currentPhase = apicommon.PhaseAppPostDeployment - if !appVersion.IsPostDeploymentSucceeded() { + if !appVersion.IsPostDeploymentSucceeded(r.Config.GetBlockDeployment()) { reconcilePostDep := func(phaseCtx context.Context) (apicommon.KeptnState, error) { return r.reconcilePhase(ctx, phaseCtx, appVersion, apicommon.PostDeploymentCheckType) } @@ -157,7 +159,7 @@ func (r *KeptnAppVersionReconciler) Reconcile(ctx context.Context, req ctrl.Requ } currentPhase = apicommon.PhaseAppPostEvaluation - if !appVersion.IsPostDeploymentEvaluationCompleted() { + if !appVersion.IsPostDeploymentEvaluationSucceeded(r.Config.GetBlockDeployment()) { reconcilePostEval := func(phaseCtx context.Context) (apicommon.KeptnState, error) { return r.reconcilePrePostEvaluation(ctx, phaseCtx, appVersion, apicommon.PostDeploymentEvaluationCheckType) } diff --git a/lifecycle-operator/controllers/lifecycle/keptnappversion/controller_test.go b/lifecycle-operator/controllers/lifecycle/keptnappversion/controller_test.go index 3fdbb71cf9..32f3128f7a 100644 --- a/lifecycle-operator/controllers/lifecycle/keptnappversion/controller_test.go +++ b/lifecycle-operator/controllers/lifecycle/keptnappversion/controller_test.go @@ -11,6 +11,7 @@ import ( "github.com/go-logr/logr" lfcv1beta1 "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1" apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1/common" + "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/config" keptncontext "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/context" "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/evaluation" evalfake "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/evaluation/fake" @@ -453,6 +454,7 @@ func setupReconciler(objs ...client.Object) (*KeptnAppVersionReconciler, chan st TracerFactory: tf, SpanHandler: spanRecorder, Meters: testcommon.InitAppMeters(), + Config: config.Instance(), EvaluationHandler: &evalfake.MockEvaluationHandler{ ReconcileEvaluationsFunc: func(ctx context.Context, phaseCtx context.Context, reconcileObject client.Object, evaluationCreateAttributes evaluation.CreateEvaluationAttributes) ([]lfcv1beta1.ItemStatus, apicommon.StatusSummary, error) { return []lfcv1beta1.ItemStatus{}, apicommon.StatusSummary{}, nil diff --git a/lifecycle-operator/controllers/lifecycle/keptnappversion/reconcile_phase.go b/lifecycle-operator/controllers/lifecycle/keptnappversion/reconcile_phase.go index b45a61b940..31aa75ca81 100644 --- a/lifecycle-operator/controllers/lifecycle/keptnappversion/reconcile_phase.go +++ b/lifecycle-operator/controllers/lifecycle/keptnappversion/reconcile_phase.go @@ -29,7 +29,7 @@ func (r *KeptnAppVersionReconciler) reconcilePhase(ctx context.Context, phaseCtx if err != nil { return apicommon.StateUnknown, err } - overallState := apicommon.GetOverallState(state) + overallState := apicommon.GetOverallStateBlockedDeployment(state, r.Config.GetBlockDeployment()) switch checkType { case apicommon.PreDeploymentCheckType: diff --git a/lifecycle-operator/controllers/lifecycle/keptnappversion/reconcile_prepostevaluation.go b/lifecycle-operator/controllers/lifecycle/keptnappversion/reconcile_prepostevaluation.go index 11629cdc54..a66b707784 100644 --- a/lifecycle-operator/controllers/lifecycle/keptnappversion/reconcile_prepostevaluation.go +++ b/lifecycle-operator/controllers/lifecycle/keptnappversion/reconcile_prepostevaluation.go @@ -21,7 +21,7 @@ func (r *KeptnAppVersionReconciler) reconcilePrePostEvaluation(ctx context.Conte return apicommon.StateUnknown, err } - overallState := apicommon.GetOverallState(state) + overallState := apicommon.GetOverallStateBlockedDeployment(state, r.Config.GetBlockDeployment()) switch checkType { case apicommon.PreDeploymentEvaluationCheckType: diff --git a/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/controller.go b/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/controller.go index 1a27f98bba..37ad0e6ebe 100644 --- a/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/controller.go +++ b/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/controller.go @@ -26,6 +26,7 @@ import ( klcv1beta1 "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1" apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1/common" controllercommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common" + "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/config" keptncontext "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/context" "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/evaluation" "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/eventsender" @@ -62,6 +63,7 @@ type KeptnWorkloadVersionReconciler struct { TracerFactory telemetry.TracerFactory EvaluationHandler evaluation.IEvaluationHandler PhaseHandler phase.IHandler + Config config.IConfig } // +kubebuilder:rbac:groups=lifecycle.keptn.sh,resources=keptnworkloadversions,verbs=get;list;watch;create;update;patch;delete @@ -153,7 +155,7 @@ func (r *KeptnWorkloadVersionReconciler) Reconcile(ctx context.Context, req ctrl } func (r *KeptnWorkloadVersionReconciler) doPreDeploymentTaskPhase(ctx context.Context, workloadVersion *klcv1beta1.KeptnWorkloadVersion, ctxWorkloadTrace context.Context) (phase.PhaseResult, error) { - if !workloadVersion.IsPreDeploymentSucceeded() { + if !workloadVersion.IsPreDeploymentSucceeded(r.Config.GetBlockDeployment()) { reconcilePre := func(phaseCtx context.Context) (apicommon.KeptnState, error) { return r.reconcilePrePostDeployment(ctx, phaseCtx, workloadVersion, apicommon.PreDeploymentCheckType) } @@ -171,7 +173,7 @@ func (r *KeptnWorkloadVersionReconciler) doPreDeploymentTaskPhase(ctx context.Co } func (r *KeptnWorkloadVersionReconciler) doPreDeploymentEvaluationPhase(ctx context.Context, workloadVersion *klcv1beta1.KeptnWorkloadVersion, ctxWorkloadTrace context.Context) (phase.PhaseResult, error) { - if !workloadVersion.IsPreDeploymentEvaluationSucceeded() { + if !workloadVersion.IsPreDeploymentEvaluationSucceeded(r.Config.GetBlockDeployment()) { reconcilePreEval := func(phaseCtx context.Context) (apicommon.KeptnState, error) { return r.reconcilePrePostEvaluation(ctx, phaseCtx, workloadVersion, apicommon.PreDeploymentEvaluationCheckType) } @@ -207,7 +209,7 @@ func (r *KeptnWorkloadVersionReconciler) doDeploymentPhase(ctx context.Context, } func (r *KeptnWorkloadVersionReconciler) doPostDeploymentTaskPhase(ctx context.Context, workloadVersion *klcv1beta1.KeptnWorkloadVersion, ctxWorkloadTrace context.Context) (phase.PhaseResult, error) { - if !workloadVersion.IsPostDeploymentCompleted() { + if !workloadVersion.IsPostDeploymentSucceeded(r.Config.GetBlockDeployment()) { reconcilePost := func(phaseCtx context.Context) (apicommon.KeptnState, error) { return r.reconcilePrePostDeployment(ctx, phaseCtx, workloadVersion, apicommon.PostDeploymentCheckType) } @@ -225,7 +227,7 @@ func (r *KeptnWorkloadVersionReconciler) doPostDeploymentTaskPhase(ctx context.C } func (r *KeptnWorkloadVersionReconciler) doPostDeploymentEvaluationPhase(ctx context.Context, workloadVersion *klcv1beta1.KeptnWorkloadVersion, ctxWorkloadTrace context.Context) (phase.PhaseResult, error) { - if !workloadVersion.IsPostDeploymentEvaluationSucceeded() { + if !workloadVersion.IsPostDeploymentEvaluationSucceeded(r.Config.GetBlockDeployment()) { reconcilePostEval := func(phaseCtx context.Context) (apicommon.KeptnState, error) { return r.reconcilePrePostEvaluation(ctx, phaseCtx, workloadVersion, apicommon.PostDeploymentEvaluationCheckType) } @@ -233,7 +235,7 @@ func (r *KeptnWorkloadVersionReconciler) doPostDeploymentEvaluationPhase(ctx con ctxWorkloadTrace, r.getTracer(), workloadVersion, - apicommon.PhaseAppPostEvaluation, + apicommon.PhaseWorkloadPostEvaluation, reconcilePostEval, ) } diff --git a/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/controller_test.go b/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/controller_test.go index d52f849148..6d9b3ff64d 100644 --- a/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/controller_test.go +++ b/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/controller_test.go @@ -10,6 +10,7 @@ import ( klcv1beta1 "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1" apicommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1/common" + "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/config" keptncontext "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/context" "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/evaluation" evaluationfake "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/evaluation/fake" @@ -22,7 +23,6 @@ import ( controllererrors "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/errors" "github.com/magiconair/properties/assert" "github.com/stretchr/testify/require" - testrequire "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/trace" appsv1 "k8s.io/api/apps/v1" @@ -51,8 +51,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_FailedReplicaSet(t * } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.Nil(t, err) - testrequire.Equal(t, apicommon.StateProgressing, keptnState) + require.Nil(t, err) + require.Equal(t, apicommon.StateProgressing, keptnState) } func TestKeptnWorkloadVersionReconciler_reconcileDeployment_UnavailableReplicaSet(t *testing.T) { @@ -69,8 +69,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_UnavailableReplicaSe } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.NotNil(t, err) - testrequire.Equal(t, apicommon.StateUnknown, keptnState) + require.NotNil(t, err) + require.Equal(t, apicommon.StateUnknown, keptnState) } func TestKeptnWorkloadVersionReconciler_reconcileDeployment_FailedStatefulSet(t *testing.T) { @@ -85,8 +85,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_FailedStatefulSet(t } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.Nil(t, err) - testrequire.Equal(t, apicommon.StateProgressing, keptnState) + require.Nil(t, err) + require.Equal(t, apicommon.StateProgressing, keptnState) } func TestKeptnWorkloadVersionReconciler_reconcileDeployment_UnavailableStatefulSet(t *testing.T) { @@ -103,8 +103,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_UnavailableStatefulS } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.NotNil(t, err) - testrequire.Equal(t, apicommon.StateUnknown, keptnState) + require.NotNil(t, err) + require.Equal(t, apicommon.StateUnknown, keptnState) } func TestKeptnWorkloadVersionReconciler_reconcileDeployment_FailedDaemonSet(t *testing.T) { @@ -119,8 +119,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_FailedDaemonSet(t *t } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.Nil(t, err) - testrequire.Equal(t, apicommon.StateProgressing, keptnState) + require.Nil(t, err) + require.Equal(t, apicommon.StateProgressing, keptnState) } func TestKeptnWorkloadVersionReconciler_reconcileDeployment_UnavailableDaemonSet(t *testing.T) { @@ -135,8 +135,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_UnavailableDaemonSet } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.NotNil(t, err) - testrequire.Equal(t, apicommon.StateUnknown, keptnState) + require.NotNil(t, err) + require.Equal(t, apicommon.StateUnknown, keptnState) } func TestKeptnWorkloadVersionReconciler_reconcileDeployment_ReadyReplicaSet(t *testing.T) { @@ -152,8 +152,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_ReadyReplicaSet(t *t } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.Nil(t, err) - testrequire.Equal(t, apicommon.StateSucceeded, keptnState) + require.Nil(t, err) + require.Equal(t, apicommon.StateSucceeded, keptnState) } func TestKeptnWorkloadVersionReconciler_reconcileDeployment_ReadyStatefulSet(t *testing.T) { @@ -169,8 +169,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_ReadyStatefulSet(t * } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.Nil(t, err) - testrequire.Equal(t, apicommon.StateSucceeded, keptnState) + require.Nil(t, err) + require.Equal(t, apicommon.StateSucceeded, keptnState) } func TestKeptnWorkloadVersionReconciler_reconcileDeployment_ReadyDaemonSet(t *testing.T) { @@ -185,8 +185,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_ReadyDaemonSet(t *te } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.Nil(t, err) - testrequire.Equal(t, apicommon.StateSucceeded, keptnState) + require.Nil(t, err) + require.Equal(t, apicommon.StateSucceeded, keptnState) } func TestKeptnWorkloadVersionReconciler_reconcileDeployment_UnsupportedReferenceKind(t *testing.T) { @@ -198,8 +198,8 @@ func TestKeptnWorkloadVersionReconciler_reconcileDeployment_UnsupportedReference } keptnState, err := r.reconcileDeployment(context.TODO(), workloadVersion) - testrequire.ErrorIs(t, err, controllererrors.ErrUnsupportedWorkloadVersionResourceReference) - testrequire.Equal(t, apicommon.StateUnknown, keptnState) + require.ErrorIs(t, err, controllererrors.ErrUnsupportedWorkloadVersionResourceReference) + require.Equal(t, apicommon.StateUnknown, keptnState) } func TestKeptnWorkloadVersionReconciler_IsPodRunning(t *testing.T) { @@ -211,7 +211,7 @@ func TestKeptnWorkloadVersionReconciler_IsPodRunning(t *testing.T) { Client: k8sfake.NewClientBuilder().WithLists(podList).Build(), } isPodRunning, err := r.isPodRunning(context.TODO(), klcv1beta1.ResourceReference{UID: "pod1"}, "node1") - testrequire.Nil(t, err) + require.Nil(t, err) if !isPodRunning { t.Errorf("Wrong!") } @@ -220,7 +220,7 @@ func TestKeptnWorkloadVersionReconciler_IsPodRunning(t *testing.T) { Client: k8sfake.NewClientBuilder().WithLists(podList2).Build(), } isPodRunning, err = r2.isPodRunning(context.TODO(), klcv1beta1.ResourceReference{UID: "pod1"}, "node1") - testrequire.Nil(t, err) + require.Nil(t, err) if isPodRunning { t.Errorf("Wrong!") } @@ -1047,6 +1047,7 @@ func setupReconciler(objs ...client.Object) (*KeptnWorkloadVersionReconciler, ch Meters: testcommon.InitAppMeters(), SpanHandler: spanHandlerMock, TracerFactory: tf, + Config: config.Instance(), EvaluationHandler: &evaluationfake.MockEvaluationHandler{ ReconcileEvaluationsFunc: func(ctx context.Context, phaseCtx context.Context, reconcileObject client.Object, evaluationCreateAttributes evaluation.CreateEvaluationAttributes) ([]klcv1beta1.ItemStatus, apicommon.StatusSummary, error) { return []klcv1beta1.ItemStatus{}, apicommon.StatusSummary{}, nil diff --git a/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/reconcile_prepostdeployment.go b/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/reconcile_prepostdeployment.go index f567dae41c..64c4bf6ee0 100644 --- a/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/reconcile_prepostdeployment.go +++ b/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/reconcile_prepostdeployment.go @@ -30,7 +30,7 @@ func (r *KeptnWorkloadVersionReconciler) reconcilePrePostDeployment(ctx context. return apicommon.StateUnknown, err } - overallState := apicommon.GetOverallState(state) + overallState := apicommon.GetOverallStateBlockedDeployment(state, r.Config.GetBlockDeployment()) switch checkType { case apicommon.PreDeploymentCheckType: diff --git a/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/reconcile_prepostevaluation.go b/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/reconcile_prepostevaluation.go index 2fd8bcd729..5694ebee1e 100644 --- a/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/reconcile_prepostevaluation.go +++ b/lifecycle-operator/controllers/lifecycle/keptnworkloadversion/reconcile_prepostevaluation.go @@ -21,7 +21,7 @@ func (r *KeptnWorkloadVersionReconciler) reconcilePrePostEvaluation(ctx context. return apicommon.StateUnknown, err } - overallState := apicommon.GetOverallState(state) + overallState := apicommon.GetOverallStateBlockedDeployment(state, r.Config.GetBlockDeployment()) switch checkType { case apicommon.PreDeploymentEvaluationCheckType: diff --git a/lifecycle-operator/main.go b/lifecycle-operator/main.go index 724c296f92..c04be36378 100644 --- a/lifecycle-operator/main.go +++ b/lifecycle-operator/main.go @@ -303,6 +303,7 @@ func main() { SpanHandler: spanHandler, EvaluationHandler: workloadVersionEvaluationHandler, PhaseHandler: workloadVersionPhaseHandler, + Config: config.Instance(), } if err = (workloadVersionReconciler).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "KeptnWorkloadVersion") @@ -337,6 +338,7 @@ func main() { EvaluationHandler: appVersionEvaluationHandler, PhaseHandler: appVersionPhaseHandler, PromotionTasksEnabled: env.PromotionTasksEnabled, + Config: config.Instance(), } if err = (appVersionReconciler).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "KeptnAppVersion") diff --git a/lifecycle-operator/test/component/appversion/appversion_suite_test.go b/lifecycle-operator/test/component/appversion/appversion_suite_test.go index 084b78a753..3d2a8973be 100644 --- a/lifecycle-operator/test/component/appversion/appversion_suite_test.go +++ b/lifecycle-operator/test/component/appversion/appversion_suite_test.go @@ -72,6 +72,7 @@ var _ = BeforeSuite(func() { TracerFactory: tracerFactory, EvaluationHandler: evaluationHandler, PhaseHandler: phaseHandler, + Config: config.Instance(), } Eventually(controller.SetupWithManager(k8sManager)).WithTimeout(30 * time.Second).WithPolling(time.Second).Should(Succeed()) close(readyToStart) diff --git a/lifecycle-operator/test/component/workloadversion/workloadversion_suite_test.go b/lifecycle-operator/test/component/workloadversion/workloadversion_suite_test.go index 6b59ec4b5c..5bedc38c0b 100644 --- a/lifecycle-operator/test/component/workloadversion/workloadversion_suite_test.go +++ b/lifecycle-operator/test/component/workloadversion/workloadversion_suite_test.go @@ -73,6 +73,7 @@ var _ = BeforeSuite(func() { TracerFactory: tracerFactory, EvaluationHandler: evaluationHandler, PhaseHandler: phaseHandler, + Config: config.Instance(), } Eventually(controller.SetupWithManager(k8sManager)).WithTimeout(30 * time.Second).WithPolling(time.Second).Should(Succeed()) close(readyToStart) diff --git a/test/chainsaw/integration/keptn-config/00-install.yaml b/test/chainsaw/integration/keptn-config/00-install.yaml deleted file mode 100644 index df7a14a465..0000000000 --- a/test/chainsaw/integration/keptn-config/00-install.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: options.keptn.sh/v1alpha1 -kind: KeptnConfig -metadata: - name: "some-config" -spec: - OTelCollectorUrl: "some-url" - blockDeployment: true diff --git a/test/chainsaw/integration/keptn-config/chainsaw-test.yaml b/test/chainsaw/integration/keptn-config/chainsaw-test.yaml deleted file mode 100755 index 5966db6479..0000000000 --- a/test/chainsaw/integration/keptn-config/chainsaw-test.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json -apiVersion: chainsaw.kyverno.io/v1alpha1 -kind: Test -metadata: - name: keptn-config -spec: - steps: - - name: step-00 - try: - - apply: - file: 00-install.yaml - - assert: - file: 00-assert.yaml - - name: step-01 - try: - - script: - content: ./get-logs.sh diff --git a/test/chainsaw/non-blocking-deployment/00-assert.yaml b/test/chainsaw/non-blocking-deployment/00-assert.yaml new file mode 100644 index 0000000000..4932c269d7 --- /dev/null +++ b/test/chainsaw/non-blocking-deployment/00-assert.yaml @@ -0,0 +1,68 @@ +apiVersion: lifecycle.keptn.sh/v1beta1 +kind: KeptnAppVersion +metadata: + name: podtato-head-0.1.0-6b86b273 +spec: + appName: podtato-head + preDeploymentTasks: + - failing-task + revision: 1 + version: 0.1.0 + workloads: + - name: podtato-head-entry + version: 0.1.0 +status: + currentPhase: Completed + postDeploymentEvaluationStatus: Succeeded + postDeploymentStatus: Succeeded + preDeploymentEvaluationStatus: Succeeded + preDeploymentStatus: Warning + preDeploymentTaskStatus: + - definitionName: failing-task + status: Failed + promotionStatus: Succeeded + status: Succeeded + workloadOverallStatus: Succeeded + workloadStatus: + - status: Succeeded + workload: + name: podtato-head-entry + version: 0.1.0 +--- +apiVersion: lifecycle.keptn.sh/v1beta1 +kind: KeptnWorkloadVersion +metadata: + generation: 1 + name: podtato-head-podtato-head-entry-0.1.0 +spec: + app: podtato-head + version: 0.1.0 + workloadName: podtato-head-podtato-head-entry +status: + currentPhase: Completed + deploymentStatus: Succeeded + postDeploymentEvaluationStatus: Succeeded + postDeploymentStatus: Warning + postDeploymentTaskStatus: + - definitionName: failing-task + status: Failed + preDeploymentEvaluationStatus: Succeeded + preDeploymentStatus: Warning + preDeploymentTaskStatus: + - definitionName: failing-task + status: Failed + status: Succeeded +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + keptn.sh/app: podtato-head + keptn.sh/post-deployment-tasks: failing-task + keptn.sh/pre-deployment-tasks: failing-task + keptn.sh/version: 0.1.0 + keptn.sh/workload: podtato-head-entry + labels: + component: podtato-head-entry +status: + phase: Running diff --git a/test/chainsaw/non-blocking-deployment/00-install.yaml b/test/chainsaw/non-blocking-deployment/00-install.yaml new file mode 100644 index 0000000000..b4d4646d1c --- /dev/null +++ b/test/chainsaw/non-blocking-deployment/00-install.yaml @@ -0,0 +1,51 @@ +apiVersion: lifecycle.keptn.sh/v1beta1 +kind: KeptnAppContext +metadata: + name: podtato-head +spec: + preDeploymentTasks: + - failing-task +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: podtato-head-entry + labels: + app: podtato-head +spec: + selector: + matchLabels: + component: podtato-head-entry + template: + metadata: + labels: + component: podtato-head-entry + annotations: + keptn.sh/app: podtato-head + keptn.sh/workload: podtato-head-entry + keptn.sh/version: 0.1.0 + keptn.sh/pre-deployment-tasks: failing-task + keptn.sh/post-deployment-tasks: failing-task + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: ghcr.io/podtato-head/entry:latest + imagePullPolicy: Always + ports: + - containerPort: 9000 + env: + - name: PODTATO_PORT + value: "9000" +--- +apiVersion: lifecycle.keptn.sh/v1beta1 +kind: KeptnTaskDefinition +metadata: + name: failing-task +spec: + function: + inline: + code: | + console.log('hello'); + exit 1; + retries: 1 diff --git a/test/chainsaw/non-blocking-deployment/01-assert.yaml b/test/chainsaw/non-blocking-deployment/01-assert.yaml new file mode 100644 index 0000000000..f001e74ec4 --- /dev/null +++ b/test/chainsaw/non-blocking-deployment/01-assert.yaml @@ -0,0 +1,49 @@ +apiVersion: lifecycle.keptn.sh/v1beta1 +kind: KeptnAppVersion +metadata: + name: podtato-head-0.2.0-d4735e3a +spec: + appName: podtato-head + preDeploymentTasks: + - failing-task + previousVersion: 0.1.0 + revision: 1 + version: 0.2.0 + workloads: + - name: podtato-head-entry + version: 0.2.0 +status: + currentPhase: AppPreDeployTasks + postDeploymentEvaluationStatus: Deprecated + postDeploymentStatus: Deprecated + preDeploymentEvaluationStatus: Deprecated + preDeploymentStatus: Failed + preDeploymentTaskStatus: + - definitionName: failing-task + status: Failed + promotionStatus: Deprecated + status: Failed + workloadOverallStatus: Deprecated +--- +apiVersion: lifecycle.keptn.sh/v1beta1 +kind: KeptnWorkloadVersion +metadata: + generation: 1 + name: podtato-head-podtato-head-entry-0.2.0 +spec: + app: podtato-head + previousVersion: 0.1.0 + version: 0.2.0 + workloadName: podtato-head-podtato-head-entry +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + keptn.sh/app: podtato-head + keptn.sh/version: 0.2.0 + keptn.sh/workload: podtato-head-entry + labels: + component: podtato-head-entry +status: + phase: Pending diff --git a/test/chainsaw/non-blocking-deployment/01-install.yaml b/test/chainsaw/non-blocking-deployment/01-install.yaml new file mode 100644 index 0000000000..15925e4cb0 --- /dev/null +++ b/test/chainsaw/non-blocking-deployment/01-install.yaml @@ -0,0 +1,49 @@ +apiVersion: lifecycle.keptn.sh/v1beta1 +kind: KeptnAppContext +metadata: + name: podtato-head +spec: + preDeploymentTasks: + - failing-task +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: podtato-head-entry + labels: + app: podtato-head +spec: + selector: + matchLabels: + component: podtato-head-entry + template: + metadata: + labels: + component: podtato-head-entry + annotations: + keptn.sh/app: podtato-head + keptn.sh/workload: podtato-head-entry + keptn.sh/version: 0.2.0 + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: ghcr.io/podtato-head/entry:0.2.8 + imagePullPolicy: Always + ports: + - containerPort: 9000 + env: + - name: PODTATO_PORT + value: "9000" +--- +apiVersion: lifecycle.keptn.sh/v1beta1 +kind: KeptnTaskDefinition +metadata: + name: failing-task +spec: + function: + inline: + code: | + console.log('hello'); + exit 1; + retries: 1 diff --git a/test/chainsaw/non-blocking-deployment/chainsaw-test.yaml b/test/chainsaw/non-blocking-deployment/chainsaw-test.yaml new file mode 100755 index 0000000000..0131b6de82 --- /dev/null +++ b/test/chainsaw/non-blocking-deployment/chainsaw-test.yaml @@ -0,0 +1,43 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: non-blocking-deployment +spec: + namespaceTemplate: + metadata: + annotations: + keptn.sh/lifecycle-toolkit: enabled + steps: + - name: step-00 + try: + - apply: + file: keptnconfig-non-blocking.yaml + - name: step-01 + try: + - script: + content: ./verify-keptnconfig.sh + - sleep: + duration: 30s + - name: step-02 + try: + - apply: + file: 00-install.yaml + - assert: + file: 00-assert.yaml + - name: step-03 + try: + - apply: + file: keptnconfig-blocking.yaml + - name: step-04 + try: + - script: + content: ./verify-keptnconfig.sh + - sleep: + duration: 30s + - name: step-05 + try: + - apply: + file: 01-install.yaml + - assert: + file: 01-assert.yaml diff --git a/test/chainsaw/integration/keptn-config/00-assert.yaml b/test/chainsaw/non-blocking-deployment/keptnconfig-blocking.yaml similarity index 64% rename from test/chainsaw/integration/keptn-config/00-assert.yaml rename to test/chainsaw/non-blocking-deployment/keptnconfig-blocking.yaml index df7a14a465..7cd8de522c 100644 --- a/test/chainsaw/integration/keptn-config/00-assert.yaml +++ b/test/chainsaw/non-blocking-deployment/keptnconfig-blocking.yaml @@ -1,7 +1,6 @@ apiVersion: options.keptn.sh/v1alpha1 kind: KeptnConfig metadata: - name: "some-config" + name: non-blocking-config spec: - OTelCollectorUrl: "some-url" blockDeployment: true diff --git a/test/chainsaw/non-blocking-deployment/keptnconfig-non-blocking.yaml b/test/chainsaw/non-blocking-deployment/keptnconfig-non-blocking.yaml new file mode 100644 index 0000000000..6f20c94d70 --- /dev/null +++ b/test/chainsaw/non-blocking-deployment/keptnconfig-non-blocking.yaml @@ -0,0 +1,6 @@ +apiVersion: options.keptn.sh/v1alpha1 +kind: KeptnConfig +metadata: + name: non-blocking-config +spec: + blockDeployment: false diff --git a/test/chainsaw/integration/keptn-config/get-logs.sh b/test/chainsaw/non-blocking-deployment/verify-keptnconfig.sh similarity index 93% rename from test/chainsaw/integration/keptn-config/get-logs.sh rename to test/chainsaw/non-blocking-deployment/verify-keptnconfig.sh index 22c5b4d4d0..82d139b708 100755 --- a/test/chainsaw/integration/keptn-config/get-logs.sh +++ b/test/chainsaw/non-blocking-deployment/verify-keptnconfig.sh @@ -8,7 +8,7 @@ for i in $(seq 1 $RETRY_COUNT); do VAR=$(kubectl logs -n "$NAMESPACE" -l control-plane=lifecycle-operator --tail=-1 | grep -c "reconciling Keptn Config") # shellcheck disable=SC1072 if [ "$VAR" -ge 1 ]; then - echo "Controller could access secret" + echo "Controller reconciled KeptnConfig" exit 0 fi if [ "$i" -lt "$RETRY_COUNT" ]; then