in pkg/controllers/nodeclass/validation.go [95:169]
func (v *Validation) Reconcile(ctx context.Context, nodeClass *v1.EC2NodeClass) (reconcile.Result, error) {
if _, ok := lo.Find(v.requiredConditions(), func(cond string) bool {
return nodeClass.StatusConditions().Get(cond).IsFalse()
}); ok {
// If any of the required status conditions are false, we know validation will fail regardless of the other values.
nodeClass.StatusConditions().SetFalse(
v1.ConditionTypeValidationSucceeded,
ConditionReasonDependenciesNotReady,
"Awaiting AMI, Instance Profile, Security Group, and Subnet resolution",
)
return reconcile.Result{}, nil
}
if _, ok := lo.Find(v.requiredConditions(), func(cond string) bool {
return nodeClass.StatusConditions().Get(cond).IsUnknown()
}); ok {
// If none of the status conditions are false, but at least one is unknown, we should also consider the validation
// state to be unknown. Once all required conditions collapse to a true or false state, we can test validation.
nodeClass.StatusConditions().SetUnknownWithReason(
v1.ConditionTypeValidationSucceeded,
ConditionReasonDependenciesNotReady,
"Awaiting AMI, Instance Profile, Security Group, and Subnet resolution",
)
return reconcile.Result{}, nil
}
nodeClaim := &karpv1.NodeClaim{
Spec: karpv1.NodeClaimSpec{
NodeClassRef: &karpv1.NodeClassReference{
Name: nodeClass.ObjectMeta.Name,
},
},
}
tags, err := utils.GetTags(nodeClass, nodeClaim, options.FromContext(ctx).ClusterName)
if err != nil {
nodeClass.StatusConditions().SetFalse(v1.ConditionTypeValidationSucceeded, ConditionReasonTagValidationFailed, err.Error())
return reconcile.Result{}, reconcile.TerminalError(fmt.Errorf("validating tags, %w", err))
}
if val, ok := v.cache.Get(v.cacheKey(nodeClass, tags)); ok {
// We still update the status condition even if it's cached since we may have had a conflict error previously
if val == "" {
nodeClass.StatusConditions().SetTrue(v1.ConditionTypeValidationSucceeded)
} else {
nodeClass.StatusConditions().SetFalse(
v1.ConditionTypeValidationSucceeded,
val.(string),
ValidationConditionMessages[val.(string)],
)
}
return reconcile.Result{}, nil
}
for _, isValid := range []validatorFunc{
v.validateCreateFleetAuthorization,
v.validateCreateLaunchTemplateAuthorization,
v.validateRunInstancesAuthorization,
} {
if failureReason, requeue, err := isValid(ctx, nodeClass, nodeClaim, tags); err != nil {
return reconcile.Result{}, err
} else if requeue {
return reconcile.Result{Requeue: true}, nil
} else if failureReason != "" {
v.cache.SetDefault(v.cacheKey(nodeClass, tags), failureReason)
nodeClass.StatusConditions().SetFalse(
v1.ConditionTypeValidationSucceeded,
failureReason,
ValidationConditionMessages[failureReason],
)
return reconcile.Result{}, nil
}
}
v.cache.SetDefault(v.cacheKey(nodeClass, tags), "")
nodeClass.StatusConditions().SetTrue(v1.ConditionTypeValidationSucceeded)
return reconcile.Result{}, nil
}