Skip to content

Commit

Permalink
Add clusterClass generation check to Cluster reconciler
Browse files Browse the repository at this point in the history
  • Loading branch information
killianmuldoon committed Jan 31, 2023
1 parent ad074ef commit a1bc637
Showing 1 changed file with 23 additions and 17 deletions.
40 changes: 23 additions & 17 deletions internal/controllers/topology/cluster/cluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,26 +175,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
return ctrl.Result{}, err
}

// Get ClusterClass.
clusterClass := &clusterv1.ClusterClass{}
key := client.ObjectKey{Name: cluster.Spec.Topology.Class, Namespace: cluster.Namespace}
if err := r.Client.Get(ctx, key, clusterClass); err != nil {
return ctrl.Result{}, errors.Wrapf(err, "failed to retrieve ClusterClass %s", cluster.Spec.Topology.Class)
}
// Default and Validate the Cluster based on information from the ClusterClass.
// This step is needed as if the ClusterClass does not exist at Cluster creation some fields may not be defaulted or
// validated in the webhook.
if errs := webhooks.DefaultVariables(cluster, clusterClass); len(errs) > 0 {
return ctrl.Result{}, apierrors.NewInvalid(clusterv1.GroupVersion.WithKind("Cluster").GroupKind(), cluster.Name, errs)
}
if errs := webhooks.ValidateClusterForClusterClass(cluster, clusterClass, field.NewPath("spec", "topology")); len(errs) > 0 {
return ctrl.Result{}, apierrors.NewInvalid(clusterv1.GroupVersion.WithKind("Cluster").GroupKind(), cluster.Name, errs)
}

// Create a scope initialized with only the cluster; during reconcile
// additional information will be added about the Cluster blueprint, current state and desired state.
s := scope.New(cluster)
s.Blueprint.ClusterClass = clusterClass

defer func() {
if err := r.reconcileConditions(s, cluster, reterr); err != nil {
Expand All @@ -221,6 +204,29 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
func (r *Reconciler) reconcile(ctx context.Context, s *scope.Scope) (ctrl.Result, error) {
var err error

// Get ClusterClass.
clusterClass := &clusterv1.ClusterClass{}
key := client.ObjectKey{Name: s.Current.Cluster.Spec.Topology.Class, Namespace: s.Current.Cluster.Namespace}
if err := r.Client.Get(ctx, key, clusterClass); err != nil {
return ctrl.Result{}, errors.Wrapf(err, "failed to retrieve ClusterClass %s", s.Current.Cluster.Spec.Topology.Class)
}

s.Blueprint.ClusterClass = clusterClass
// If the ClusterClass `metadata.Generation` doesn't match the `status.ObservedGeneration` requeue as the ClusterClass
// is not up to date.
if clusterClass.GetGeneration() != clusterClass.Status.ObservedGeneration {
return ctrl.Result{}, errors.Errorf("ClusterClass %s not up to date. Requeuing", clusterClass.Name)
}

// Default and Validate the Cluster based on information from the ClusterClass.
// This step is needed as if the ClusterClass does not exist at Cluster creation some fields may not be defaulted or
// validated in the webhook.
if errs := webhooks.DefaultVariables(s.Current.Cluster, clusterClass); len(errs) > 0 {
return ctrl.Result{}, apierrors.NewInvalid(clusterv1.GroupVersion.WithKind("Cluster").GroupKind(), s.Current.Cluster.Name, errs)
}
if errs := webhooks.ValidateClusterForClusterClass(s.Current.Cluster, clusterClass, field.NewPath("spec", "topology")); len(errs) > 0 {
return ctrl.Result{}, apierrors.NewInvalid(clusterv1.GroupVersion.WithKind("Cluster").GroupKind(), s.Current.Cluster.Name, errs)
}
// Gets the blueprint with the ClusterClass and the referenced templates
// and store it in the request scope.
s.Blueprint, err = r.getBlueprint(ctx, s.Current.Cluster, s.Blueprint.ClusterClass)
Expand Down

0 comments on commit a1bc637

Please sign in to comment.