diff --git a/pkg/cloudprovider/types.go b/pkg/cloudprovider/types.go index bb42dd0372..6c7f986230 100644 --- a/pkg/cloudprovider/types.go +++ b/pkg/cloudprovider/types.go @@ -373,3 +373,16 @@ func IsNodeClassNotReadyError(err error) bool { var nrError *NodeClassNotReadyError return errors.As(err, &nrError) } + +// CreateError is an error type returned by CloudProviders when instance creation fails +type CreateError struct { + error + ConditionMessage string +} + +func NewCreateError(err error, message string) *CreateError { + return &CreateError{ + error: err, + ConditionMessage: message, + } +} diff --git a/pkg/controllers/nodeclaim/lifecycle/launch.go b/pkg/controllers/nodeclaim/lifecycle/launch.go index da93b5cc18..fc5fe0baf3 100644 --- a/pkg/controllers/nodeclaim/lifecycle/launch.go +++ b/pkg/controllers/nodeclaim/lifecycle/launch.go @@ -18,6 +18,7 @@ package lifecycle import ( "context" + "errors" "fmt" "github.com/patrickmn/go-cache" @@ -98,7 +99,12 @@ func (l *Launch) launchNodeClaim(ctx context.Context, nodeClaim *v1.NodeClaim) ( }) return nil, nil default: - nodeClaim.StatusConditions().SetUnknownWithReason(v1.ConditionTypeLaunched, "LaunchFailed", truncateMessage(err.Error())) + var createError *cloudprovider.CreateError + if errors.As(err, &createError) { + nodeClaim.StatusConditions().SetUnknownWithReason(v1.ConditionTypeLaunched, "LaunchFailed", createError.ConditionMessage) + } else { + nodeClaim.StatusConditions().SetUnknownWithReason(v1.ConditionTypeLaunched, "LaunchFailed", truncateMessage(err.Error())) + } return nil, fmt.Errorf("launching nodeclaim, %w", err) } } diff --git a/pkg/controllers/nodeclaim/lifecycle/launch_test.go b/pkg/controllers/nodeclaim/lifecycle/launch_test.go index c9b19c4ff6..2e69ceca87 100644 --- a/pkg/controllers/nodeclaim/lifecycle/launch_test.go +++ b/pkg/controllers/nodeclaim/lifecycle/launch_test.go @@ -82,4 +82,15 @@ var _ = Describe("Launch", func() { ExpectFinalizersRemoved(ctx, env.Client, nodeClaim) ExpectNotFound(ctx, env.Client, nodeClaim) }) + It("should set nodeClaim status condition from the condition message received if error returned is CreateError", func() { + conditionMessage := "instance creation failed" + cloudProvider.NextCreateErr = cloudprovider.NewCreateError(fmt.Errorf("error launching instance"), conditionMessage) + nodeClaim := test.NodeClaim() + ExpectApplied(ctx, env.Client, nodeClaim) + _ = ExpectObjectReconcileFailed(ctx, env.Client, nodeClaimController, nodeClaim) + nodeClaim = ExpectExists(ctx, env.Client, nodeClaim) + condition := ExpectStatusConditionExists(nodeClaim, v1.ConditionTypeLaunched) + Expect(condition.Status).To(Equal(metav1.ConditionUnknown)) + Expect(condition.Message).To(Equal(conditionMessage)) + }) })