@@ -17,9 +17,11 @@ limitations under the License.
1717package controllers
1818
1919import (
20+ "fmt"
21+ "strings"
22+
2023 "github.com/pkg/errors"
2124 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22- kerrors "k8s.io/apimachinery/pkg/util/errors"
2325 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
2426 controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
2527 "sigs.k8s.io/cluster-api/util"
@@ -70,9 +72,7 @@ func (r Reconciler) Reconcile(ctx *context.ClusterContext) (reconcile.Result, er
7072 return reconcile.Result {}, err
7173 }
7274
73- var errList []error
7475 clusterModuleSpecs := []infrav1.ClusterModule {}
75-
7676 for _ , mod := range ctx .VSphereCluster .Spec .ClusterModules {
7777 curr := mod .TargetObjectName
7878 if mod .ControlPlane {
@@ -84,14 +84,14 @@ func (r Reconciler) Reconcile(ctx *context.ClusterContext) (reconcile.Result, er
8484 if err := r .ClusterModuleService .Remove (ctx , mod .ModuleUUID ); err != nil {
8585 ctx .Logger .Error (err , "failed to delete cluster module for object" ,
8686 "name" , mod .TargetObjectName , "moduleUUID" , mod .ModuleUUID )
87- errList = append (errList , err )
8887 }
8988 delete (objectMap , curr )
9089 } else {
9190 // verify the cluster module
9291 exists , err := r .ClusterModuleService .DoesExist (ctx , obj , mod .ModuleUUID )
9392 if err != nil {
94- errList = append (errList , err )
93+ ctx .Logger .Error (err , "failed to verify cluster module for object" ,
94+ "name" , mod .TargetObjectName , "moduleUUID" , mod .ModuleUUID )
9595 }
9696 // append the module and object info to the VSphereCluster object
9797 // and remove it from the object map since no new cluster module
@@ -110,17 +110,14 @@ func (r Reconciler) Reconcile(ctx *context.ClusterContext) (reconcile.Result, er
110110 }
111111 }
112112 }
113- if len (errList ) > 0 {
114- ctx .Logger .Error (kerrors .NewAggregate (errList ), "errors reconciling cluster modules for cluster" ,
115- "namespace" , ctx .VSphereCluster .Namespace , "name" , ctx .VSphereCluster .Name )
116- }
117113
118- errList = []error {}
114+ modErrs : = []clusterModError {}
119115 for _ , obj := range objectMap {
120116 moduleUUID , err := r .ClusterModuleService .Create (ctx , obj )
121117 if err != nil {
122118 ctx .Logger .Error (err , "failed to create cluster module for target object" , "name" , obj .GetName ())
123- errList = append (errList , err )
119+ modErrs = append (modErrs , clusterModError {obj .GetName (), err })
120+ continue
124121 }
125122 clusterModuleSpecs = append (clusterModuleSpecs , infrav1.ClusterModule {
126123 ControlPlane : obj .IsControlPlane (),
@@ -130,16 +127,19 @@ func (r Reconciler) Reconcile(ctx *context.ClusterContext) (reconcile.Result, er
130127 }
131128 ctx .VSphereCluster .Spec .ClusterModules = clusterModuleSpecs
132129
133- if len (errList ) > 0 {
134- err = kerrors .NewAggregate (errList )
135- ctx .Logger .Error (err , "errors reconciling cluster modules for cluster" ,
136- "namespace" , ctx .VSphereCluster .Namespace , "name" , ctx .VSphereCluster .Name )
137- }
138-
139130 switch {
140- case err != nil :
141- conditions .MarkFalse (ctx .VSphereCluster , infrav1 .ClusterModulesAvailableCondition , infrav1 .ClusterModuleSetupFailedReason , clusterv1 .ConditionSeverityWarning , err .Error ())
142- case err == nil && len (clusterModuleSpecs ) > 0 :
131+ case len (modErrs ) > 0 :
132+ incompatibleOwnerErrs := incompatibleOwnerErrors (modErrs )
133+ // if cluster module creation is not possible due to incompatibility,
134+ // cluster creation should succeed with a warning condition
135+ if len (incompatibleOwnerErrs ) > 0 && len (incompatibleOwnerErrs ) == len (modErrs ) {
136+ err = nil
137+ } else {
138+ err = errors .New (generateClusterModuleErrorMessage (modErrs ))
139+ }
140+ conditions .MarkFalse (ctx .VSphereCluster , infrav1 .ClusterModulesAvailableCondition , infrav1 .ClusterModuleSetupFailedReason ,
141+ clusterv1 .ConditionSeverityWarning , generateClusterModuleErrorMessage (modErrs ))
142+ case len (modErrs ) == 0 && len (clusterModuleSpecs ) > 0 :
143143 conditions .MarkTrue (ctx .VSphereCluster , infrav1 .ClusterModulesAvailableCondition )
144144 default :
145145 conditions .Delete (ctx .VSphereCluster , infrav1 .ClusterModulesAvailableCondition )
@@ -253,3 +253,29 @@ func (r Reconciler) fetchMachineOwnerObjects(ctx *context.ClusterContext) (map[s
253253func appendKCPKey (name string ) string {
254254 return "kcp" + name
255255}
256+
257+ func incompatibleOwnerErrors (errList []clusterModError ) []clusterModError {
258+ toReport := []clusterModError {}
259+ for _ , e := range errList {
260+ if clustermodule .IsIncompatibleOwnerError (e .err ) {
261+ toReport = append (toReport , e )
262+ }
263+ }
264+ return toReport
265+ }
266+
267+ type clusterModError struct {
268+ name string
269+ err error
270+ }
271+
272+ func generateClusterModuleErrorMessage (errList []clusterModError ) string {
273+ sb := strings.Builder {}
274+ sb .WriteString ("failed to create cluster modules for: " )
275+
276+ for _ , e := range errList {
277+ sb .WriteString (fmt .Sprintf ("%s %s, " , e .name , e .err .Error ()))
278+ }
279+ msg := sb .String ()
280+ return msg [:len (msg )- 2 ]
281+ }
0 commit comments