@@ -175,26 +175,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
175175 return ctrl.Result {}, err
176176 }
177177
178- // Get ClusterClass.
179- clusterClass := & clusterv1.ClusterClass {}
180- key := client.ObjectKey {Name : cluster .Spec .Topology .Class , Namespace : cluster .Namespace }
181- if err := r .Client .Get (ctx , key , clusterClass ); err != nil {
182- return ctrl.Result {}, errors .Wrapf (err , "failed to retrieve ClusterClass %s" , cluster .Spec .Topology .Class )
183- }
184- // Default and Validate the Cluster based on information from the ClusterClass.
185- // This step is needed as if the ClusterClass does not exist at Cluster creation some fields may not be defaulted or
186- // validated in the webhook.
187- if errs := webhooks .DefaultVariables (cluster , clusterClass ); len (errs ) > 0 {
188- return ctrl.Result {}, apierrors .NewInvalid (clusterv1 .GroupVersion .WithKind ("Cluster" ).GroupKind (), cluster .Name , errs )
189- }
190- if errs := webhooks .ValidateClusterForClusterClass (cluster , clusterClass , field .NewPath ("spec" , "topology" )); len (errs ) > 0 {
191- return ctrl.Result {}, apierrors .NewInvalid (clusterv1 .GroupVersion .WithKind ("Cluster" ).GroupKind (), cluster .Name , errs )
192- }
193-
194178 // Create a scope initialized with only the cluster; during reconcile
195179 // additional information will be added about the Cluster blueprint, current state and desired state.
196180 s := scope .New (cluster )
197- s .Blueprint .ClusterClass = clusterClass
198181
199182 defer func () {
200183 if err := r .reconcileConditions (s , cluster , reterr ); err != nil {
@@ -221,6 +204,31 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
221204func (r * Reconciler ) reconcile (ctx context.Context , s * scope.Scope ) (ctrl.Result , error ) {
222205 var err error
223206
207+ // Get ClusterClass.
208+ clusterClass := & clusterv1.ClusterClass {}
209+ key := client.ObjectKey {Name : s .Current .Cluster .Spec .Topology .Class , Namespace : s .Current .Cluster .Namespace }
210+ if err := r .Client .Get (ctx , key , clusterClass ); err != nil {
211+ return ctrl.Result {}, errors .Wrapf (err , "failed to retrieve ClusterClass %s" , s .Current .Cluster .Spec .Topology .Class )
212+ }
213+
214+ s .Blueprint .ClusterClass = clusterClass
215+ // If the ClusterClass `metadata.Generation` doesn't match the `status.ObservedGeneration` return as the ClusterClass
216+ // is not up to date.
217+ // Note: This doesn't require requeue as a change to ClusterClass observedGeneration will cause an additional reconcile
218+ // in the Cluster.
219+ if clusterClass .GetGeneration () != clusterClass .Status .ObservedGeneration {
220+ return ctrl.Result {}, nil
221+ }
222+
223+ // Default and Validate the Cluster based on information from the ClusterClass.
224+ // This step is needed as if the ClusterClass does not exist at Cluster creation some fields may not be defaulted or
225+ // validated in the webhook.
226+ if errs := webhooks .DefaultVariables (s .Current .Cluster , clusterClass ); len (errs ) > 0 {
227+ return ctrl.Result {}, apierrors .NewInvalid (clusterv1 .GroupVersion .WithKind ("Cluster" ).GroupKind (), s .Current .Cluster .Name , errs )
228+ }
229+ if errs := webhooks .ValidateClusterForClusterClass (s .Current .Cluster , clusterClass , field .NewPath ("spec" , "topology" )); len (errs ) > 0 {
230+ return ctrl.Result {}, apierrors .NewInvalid (clusterv1 .GroupVersion .WithKind ("Cluster" ).GroupKind (), s .Current .Cluster .Name , errs )
231+ }
224232 // Gets the blueprint with the ClusterClass and the referenced templates
225233 // and store it in the request scope.
226234 s .Blueprint , err = r .getBlueprint (ctx , s .Current .Cluster , s .Blueprint .ClusterClass )
0 commit comments