From 2e00fea034a7b277f418a8db2c4f8f70e1e56078 Mon Sep 17 00:00:00 2001 From: Antonin Bas Date: Wed, 9 Aug 2023 14:13:28 -0700 Subject: [PATCH] [k8s] Fix panic in WaitUntilDeploymentAvailable The `func (err DeploymentNotAvailable) Error()` method should not assume that `Status.Conditions[0]` is always valid for the Deployment. Fixes #1329 Signed-off-by: Antonin Bas --- modules/k8s/deployment.go | 17 ++++++++++------- modules/k8s/errors.go | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/modules/k8s/deployment.go b/modules/k8s/deployment.go index 14225bb97e..c713d0ff97 100644 --- a/modules/k8s/deployment.go +++ b/modules/k8s/deployment.go @@ -98,13 +98,16 @@ func WaitUntilDeploymentAvailableE( // IsDeploymentAvailable returns true if all pods within the deployment are ready and started func IsDeploymentAvailable(deploy *appsv1.Deployment) bool { - for _, dc := range deploy.Status.Conditions { - if dc.Type == appsv1.DeploymentProgressing && - dc.Status == v1.ConditionTrue && - dc.Reason == "NewReplicaSetAvailable" { - return true + dc := getDeploymentCondition(deploy, appsv1.DeploymentProgressing) + return dc != nil && dc.Status == v1.ConditionTrue && dc.Reason == "NewReplicaSetAvailable" +} + +func getDeploymentCondition(deploy *appsv1.Deployment, cType appsv1.DeploymentConditionType) *appsv1.DeploymentCondition { + for idx := range deploy.Status.Conditions { + dc := &deploy.Status.Conditions[idx] + if dc.Type == cType { + return dc } } - - return false + return nil } diff --git a/modules/k8s/errors.go b/modules/k8s/errors.go index da87bb640c..1b098b2e38 100644 --- a/modules/k8s/errors.go +++ b/modules/k8s/errors.go @@ -69,11 +69,21 @@ type DeploymentNotAvailable struct { // Error is a simple function to return a formatted error message as a string func (err DeploymentNotAvailable) Error() string { + dc := getDeploymentCondition(err.deploy, appsv1.DeploymentProgressing) + if dc == nil { + return fmt.Sprintf( + "Deployment %s is not available, missing '%s' condition", + err.deploy.Name, + appsv1.DeploymentProgressing, + ) + } return fmt.Sprintf( - "Deployment %s is not available, reason: %s, message: %s", + "Deployment %s is not available as '%s' condition indicates that the Deployment is not complete, status: %v, reason: %s, message: %s", err.deploy.Name, - err.deploy.Status.Conditions[0].Reason, - err.deploy.Status.Conditions[0].Message, + appsv1.DeploymentProgressing, + dc.Status, + dc.Reason, + dc.Message, ) }