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 }