sigs.k8s.io/cluster-api@v1.7.1/internal/controllers/topology/cluster/blueprint.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package cluster
    18  
    19  import (
    20  	"context"
    21  
    22  	"github.com/pkg/errors"
    23  
    24  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    25  	"sigs.k8s.io/cluster-api/exp/topology/scope"
    26  	tlog "sigs.k8s.io/cluster-api/internal/log"
    27  )
    28  
    29  // getBlueprint gets a ClusterBlueprint with the ClusterClass and the referenced templates to be used for a managed Cluster topology.
    30  // It also converts and patches all ObjectReferences in ClusterClass and ControlPlane to the latest apiVersion of the current contract.
    31  // NOTE: This function assumes that cluster.Spec.Topology.Class is set.
    32  func (r *Reconciler) getBlueprint(ctx context.Context, cluster *clusterv1.Cluster, clusterClass *clusterv1.ClusterClass) (_ *scope.ClusterBlueprint, reterr error) {
    33  	blueprint := &scope.ClusterBlueprint{
    34  		Topology:           cluster.Spec.Topology,
    35  		ClusterClass:       clusterClass,
    36  		MachineDeployments: map[string]*scope.MachineDeploymentBlueprint{},
    37  		MachinePools:       map[string]*scope.MachinePoolBlueprint{},
    38  	}
    39  
    40  	var err error
    41  	// Get ClusterClass.spec.infrastructure.
    42  	blueprint.InfrastructureClusterTemplate, err = r.getReference(ctx, blueprint.ClusterClass.Spec.Infrastructure.Ref)
    43  	if err != nil {
    44  		return nil, errors.Wrapf(err, "failed to get infrastructure cluster template for %s", tlog.KObj{Obj: blueprint.ClusterClass})
    45  	}
    46  
    47  	// Get ClusterClass.spec.controlPlane.
    48  	blueprint.ControlPlane = &scope.ControlPlaneBlueprint{}
    49  	blueprint.ControlPlane.Template, err = r.getReference(ctx, blueprint.ClusterClass.Spec.ControlPlane.Ref)
    50  	if err != nil {
    51  		return nil, errors.Wrapf(err, "failed to get control plane template for %s", tlog.KObj{Obj: blueprint.ClusterClass})
    52  	}
    53  
    54  	// If the clusterClass mandates the controlPlane has infrastructureMachines, read it.
    55  	if blueprint.HasControlPlaneInfrastructureMachine() {
    56  		blueprint.ControlPlane.InfrastructureMachineTemplate, err = r.getReference(ctx, blueprint.ClusterClass.Spec.ControlPlane.MachineInfrastructure.Ref)
    57  		if err != nil {
    58  			return nil, errors.Wrapf(err, "failed to get control plane's machine template for %s", tlog.KObj{Obj: blueprint.ClusterClass})
    59  		}
    60  	}
    61  
    62  	// If the clusterClass defines a valid MachineHealthCheck (including a defined MachineInfrastructure) set the blueprint MachineHealthCheck.
    63  	if blueprint.HasControlPlaneMachineHealthCheck() {
    64  		blueprint.ControlPlane.MachineHealthCheck = blueprint.ClusterClass.Spec.ControlPlane.MachineHealthCheck
    65  	}
    66  
    67  	// Loop over the machine deployments classes in ClusterClass
    68  	// and fetch the related templates.
    69  	for _, machineDeploymentClass := range blueprint.ClusterClass.Spec.Workers.MachineDeployments {
    70  		machineDeploymentBlueprint := &scope.MachineDeploymentBlueprint{}
    71  
    72  		// Make sure to copy the metadata from the blueprint, which is later layered
    73  		// with the additional metadata defined in the Cluster's topology section
    74  		// for the MachineDeployment that is created or updated.
    75  		machineDeploymentClass.Template.Metadata.DeepCopyInto(&machineDeploymentBlueprint.Metadata)
    76  
    77  		// Get the infrastructure machine template.
    78  		machineDeploymentBlueprint.InfrastructureMachineTemplate, err = r.getReference(ctx, machineDeploymentClass.Template.Infrastructure.Ref)
    79  		if err != nil {
    80  			return nil, errors.Wrapf(err, "failed to get infrastructure machine template for %s, MachineDeployment class %q", tlog.KObj{Obj: blueprint.ClusterClass}, machineDeploymentClass.Class)
    81  		}
    82  
    83  		// Get the bootstrap config template.
    84  		machineDeploymentBlueprint.BootstrapTemplate, err = r.getReference(ctx, machineDeploymentClass.Template.Bootstrap.Ref)
    85  		if err != nil {
    86  			return nil, errors.Wrapf(err, "failed to get bootstrap config template for %s, MachineDeployment class %q", tlog.KObj{Obj: blueprint.ClusterClass}, machineDeploymentClass.Class)
    87  		}
    88  
    89  		// If the machineDeploymentClass defines a MachineHealthCheck add it to the blueprint.
    90  		if machineDeploymentClass.MachineHealthCheck != nil {
    91  			machineDeploymentBlueprint.MachineHealthCheck = machineDeploymentClass.MachineHealthCheck
    92  		}
    93  		blueprint.MachineDeployments[machineDeploymentClass.Class] = machineDeploymentBlueprint
    94  	}
    95  
    96  	// Loop over the machine pool classes in ClusterClass
    97  	// and fetch the related templates.
    98  	for _, machinePoolClass := range blueprint.ClusterClass.Spec.Workers.MachinePools {
    99  		machinePoolBlueprint := &scope.MachinePoolBlueprint{}
   100  
   101  		// Make sure to copy the metadata from the blueprint, which is later layered
   102  		// with the additional metadata defined in the Cluster's topology section
   103  		// for the MachinePool that is created or updated.
   104  		machinePoolClass.Template.Metadata.DeepCopyInto(&machinePoolBlueprint.Metadata)
   105  
   106  		// Get the InfrastructureMachinePoolTemplate.
   107  		machinePoolBlueprint.InfrastructureMachinePoolTemplate, err = r.getReference(ctx, machinePoolClass.Template.Infrastructure.Ref)
   108  		if err != nil {
   109  			return nil, errors.Wrapf(err, "failed to get InfrastructureMachinePoolTemplate for %s, MachinePool class %q", tlog.KObj{Obj: blueprint.ClusterClass}, machinePoolClass.Class)
   110  		}
   111  
   112  		// Get the bootstrap config template.
   113  		machinePoolBlueprint.BootstrapTemplate, err = r.getReference(ctx, machinePoolClass.Template.Bootstrap.Ref)
   114  		if err != nil {
   115  			return nil, errors.Wrapf(err, "failed to get bootstrap config for %s, MachinePool class %q", tlog.KObj{Obj: blueprint.ClusterClass}, machinePoolClass.Class)
   116  		}
   117  
   118  		blueprint.MachinePools[machinePoolClass.Class] = machinePoolBlueprint
   119  	}
   120  
   121  	return blueprint, nil
   122  }