sigs.k8s.io/cluster-api@v1.7.1/internal/test/builder/builders.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 builder
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  
    23  	corev1 "k8s.io/api/core/v1"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    26  	"k8s.io/apimachinery/pkg/util/intstr"
    27  
    28  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    29  	expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
    30  )
    31  
    32  // ClusterBuilder holds the variables and objects required to build a clusterv1.Cluster.
    33  type ClusterBuilder struct {
    34  	namespace             string
    35  	name                  string
    36  	labels                map[string]string
    37  	annotations           map[string]string
    38  	topology              *clusterv1.Topology
    39  	infrastructureCluster *unstructured.Unstructured
    40  	controlPlane          *unstructured.Unstructured
    41  	network               *clusterv1.ClusterNetwork
    42  }
    43  
    44  // Cluster returns a ClusterBuilder with the given name and namespace.
    45  func Cluster(namespace, name string) *ClusterBuilder {
    46  	return &ClusterBuilder{
    47  		namespace: namespace,
    48  		name:      name,
    49  	}
    50  }
    51  
    52  // WithClusterNetwork sets the ClusterNetwork for the ClusterBuilder.
    53  func (c *ClusterBuilder) WithClusterNetwork(clusterNetwork *clusterv1.ClusterNetwork) *ClusterBuilder {
    54  	c.network = clusterNetwork
    55  	return c
    56  }
    57  
    58  // WithLabels sets the labels for the ClusterBuilder.
    59  func (c *ClusterBuilder) WithLabels(labels map[string]string) *ClusterBuilder {
    60  	c.labels = labels
    61  	return c
    62  }
    63  
    64  // WithAnnotations sets the annotations for the ClusterBuilder.
    65  func (c *ClusterBuilder) WithAnnotations(annotations map[string]string) *ClusterBuilder {
    66  	c.annotations = annotations
    67  	return c
    68  }
    69  
    70  // WithInfrastructureCluster adds the passed InfrastructureCluster to the ClusterBuilder.
    71  func (c *ClusterBuilder) WithInfrastructureCluster(t *unstructured.Unstructured) *ClusterBuilder {
    72  	c.infrastructureCluster = t
    73  	return c
    74  }
    75  
    76  // WithControlPlane adds the passed ControlPlane to the ClusterBuilder.
    77  func (c *ClusterBuilder) WithControlPlane(t *unstructured.Unstructured) *ClusterBuilder {
    78  	c.controlPlane = t
    79  	return c
    80  }
    81  
    82  // WithTopology adds the passed Topology object to the ClusterBuilder.
    83  func (c *ClusterBuilder) WithTopology(topology *clusterv1.Topology) *ClusterBuilder {
    84  	c.topology = topology
    85  	return c
    86  }
    87  
    88  // Build returns a Cluster with the attributes added to the ClusterBuilder.
    89  func (c *ClusterBuilder) Build() *clusterv1.Cluster {
    90  	obj := &clusterv1.Cluster{
    91  		TypeMeta: metav1.TypeMeta{
    92  			Kind:       "Cluster",
    93  			APIVersion: clusterv1.GroupVersion.String(),
    94  		},
    95  		ObjectMeta: metav1.ObjectMeta{
    96  			Name:        c.name,
    97  			Namespace:   c.namespace,
    98  			Labels:      c.labels,
    99  			Annotations: c.annotations,
   100  		},
   101  		Spec: clusterv1.ClusterSpec{
   102  			Topology:       c.topology,
   103  			ClusterNetwork: c.network,
   104  		},
   105  	}
   106  	if c.infrastructureCluster != nil {
   107  		obj.Spec.InfrastructureRef = objToRef(c.infrastructureCluster)
   108  	}
   109  	if c.controlPlane != nil {
   110  		obj.Spec.ControlPlaneRef = objToRef(c.controlPlane)
   111  	}
   112  	return obj
   113  }
   114  
   115  // ClusterTopologyBuilder contains the fields needed to build a testable ClusterTopology.
   116  type ClusterTopologyBuilder struct {
   117  	class                string
   118  	workers              *clusterv1.WorkersTopology
   119  	version              string
   120  	controlPlaneReplicas int32
   121  	controlPlaneMHC      *clusterv1.MachineHealthCheckTopology
   122  	variables            []clusterv1.ClusterVariable
   123  }
   124  
   125  // ClusterTopology returns a ClusterTopologyBuilder.
   126  func ClusterTopology() *ClusterTopologyBuilder {
   127  	return &ClusterTopologyBuilder{
   128  		workers: &clusterv1.WorkersTopology{},
   129  	}
   130  }
   131  
   132  // WithClass adds the passed ClusterClass name to the ClusterTopologyBuilder.
   133  func (c *ClusterTopologyBuilder) WithClass(class string) *ClusterTopologyBuilder {
   134  	c.class = class
   135  	return c
   136  }
   137  
   138  // WithVersion adds the passed version to the ClusterTopologyBuilder.
   139  func (c *ClusterTopologyBuilder) WithVersion(version string) *ClusterTopologyBuilder {
   140  	c.version = version
   141  	return c
   142  }
   143  
   144  // WithControlPlaneReplicas adds the passed replicas value to the ClusterTopologyBuilder.
   145  func (c *ClusterTopologyBuilder) WithControlPlaneReplicas(replicas int32) *ClusterTopologyBuilder {
   146  	c.controlPlaneReplicas = replicas
   147  	return c
   148  }
   149  
   150  // WithControlPlaneMachineHealthCheck adds MachineHealthCheckTopology used as the MachineHealthCheck value.
   151  func (c *ClusterTopologyBuilder) WithControlPlaneMachineHealthCheck(mhc *clusterv1.MachineHealthCheckTopology) *ClusterTopologyBuilder {
   152  	c.controlPlaneMHC = mhc
   153  	return c
   154  }
   155  
   156  // WithMachineDeployment passes the full MachineDeploymentTopology and adds it to an existing list in the ClusterTopologyBuilder.
   157  func (c *ClusterTopologyBuilder) WithMachineDeployment(mdc clusterv1.MachineDeploymentTopology) *ClusterTopologyBuilder {
   158  	c.workers.MachineDeployments = append(c.workers.MachineDeployments, mdc)
   159  	return c
   160  }
   161  
   162  // WithMachinePool passes the full MachinePoolTopology and adds it to an existing list in the ClusterTopologyBuilder.
   163  func (c *ClusterTopologyBuilder) WithMachinePool(mpc clusterv1.MachinePoolTopology) *ClusterTopologyBuilder {
   164  	c.workers.MachinePools = append(c.workers.MachinePools, mpc)
   165  	return c
   166  }
   167  
   168  // WithVariables adds the passed variables to the ClusterTopologyBuilder.
   169  func (c *ClusterTopologyBuilder) WithVariables(vars ...clusterv1.ClusterVariable) *ClusterTopologyBuilder {
   170  	c.variables = vars
   171  	return c
   172  }
   173  
   174  // Build returns a testable cluster Topology object with any values passed to the builder.
   175  func (c *ClusterTopologyBuilder) Build() *clusterv1.Topology {
   176  	return &clusterv1.Topology{
   177  		Class:   c.class,
   178  		Workers: c.workers,
   179  		Version: c.version,
   180  		ControlPlane: clusterv1.ControlPlaneTopology{
   181  			Replicas:           &c.controlPlaneReplicas,
   182  			MachineHealthCheck: c.controlPlaneMHC,
   183  		},
   184  		Variables: c.variables,
   185  	}
   186  }
   187  
   188  // MachineDeploymentTopologyBuilder holds the values needed to create a testable MachineDeploymentTopology.
   189  type MachineDeploymentTopologyBuilder struct {
   190  	class     string
   191  	name      string
   192  	replicas  *int32
   193  	mhc       *clusterv1.MachineHealthCheckTopology
   194  	variables []clusterv1.ClusterVariable
   195  }
   196  
   197  // MachineDeploymentTopology returns a builder used to create a testable MachineDeploymentTopology.
   198  func MachineDeploymentTopology(name string) *MachineDeploymentTopologyBuilder {
   199  	return &MachineDeploymentTopologyBuilder{
   200  		name: name,
   201  	}
   202  }
   203  
   204  // WithClass adds a class string used as the MachineDeploymentTopology class.
   205  func (m *MachineDeploymentTopologyBuilder) WithClass(class string) *MachineDeploymentTopologyBuilder {
   206  	m.class = class
   207  	return m
   208  }
   209  
   210  // WithReplicas adds a replicas value used as the MachineDeploymentTopology replicas value.
   211  func (m *MachineDeploymentTopologyBuilder) WithReplicas(replicas int32) *MachineDeploymentTopologyBuilder {
   212  	m.replicas = &replicas
   213  	return m
   214  }
   215  
   216  // WithVariables adds variables used as the MachineDeploymentTopology variables value.
   217  func (m *MachineDeploymentTopologyBuilder) WithVariables(variables ...clusterv1.ClusterVariable) *MachineDeploymentTopologyBuilder {
   218  	m.variables = variables
   219  	return m
   220  }
   221  
   222  // WithMachineHealthCheck adds MachineHealthCheckTopology used as the MachineHealthCheck value.
   223  func (m *MachineDeploymentTopologyBuilder) WithMachineHealthCheck(mhc *clusterv1.MachineHealthCheckTopology) *MachineDeploymentTopologyBuilder {
   224  	m.mhc = mhc
   225  	return m
   226  }
   227  
   228  // Build returns a testable MachineDeploymentTopology with any values passed to the builder.
   229  func (m *MachineDeploymentTopologyBuilder) Build() clusterv1.MachineDeploymentTopology {
   230  	md := clusterv1.MachineDeploymentTopology{
   231  		Class:              m.class,
   232  		Name:               m.name,
   233  		Replicas:           m.replicas,
   234  		MachineHealthCheck: m.mhc,
   235  	}
   236  
   237  	if len(m.variables) > 0 {
   238  		md.Variables = &clusterv1.MachineDeploymentVariables{
   239  			Overrides: m.variables,
   240  		}
   241  	}
   242  
   243  	return md
   244  }
   245  
   246  // MachinePoolTopologyBuilder holds the values needed to create a testable MachinePoolTopology.
   247  type MachinePoolTopologyBuilder struct {
   248  	class          string
   249  	name           string
   250  	replicas       *int32
   251  	failureDomains []string
   252  	variables      []clusterv1.ClusterVariable
   253  }
   254  
   255  // MachinePoolTopology returns a builder used to create a testable MachinePoolTopology.
   256  func MachinePoolTopology(name string) *MachinePoolTopologyBuilder {
   257  	return &MachinePoolTopologyBuilder{
   258  		name: name,
   259  	}
   260  }
   261  
   262  // WithClass adds a class string used as the MachinePoolTopology class.
   263  func (m *MachinePoolTopologyBuilder) WithClass(class string) *MachinePoolTopologyBuilder {
   264  	m.class = class
   265  	return m
   266  }
   267  
   268  // WithReplicas adds a replicas value used as the MachinePoolTopology replicas value.
   269  func (m *MachinePoolTopologyBuilder) WithReplicas(replicas int32) *MachinePoolTopologyBuilder {
   270  	m.replicas = &replicas
   271  	return m
   272  }
   273  
   274  // WithFailureDomains adds a failureDomains value used as the MachinePoolTopology failureDomains value.
   275  func (m *MachinePoolTopologyBuilder) WithFailureDomains(failureDomains ...string) *MachinePoolTopologyBuilder {
   276  	m.failureDomains = failureDomains
   277  	return m
   278  }
   279  
   280  // WithVariables adds variables used as the MachinePoolTopology variables value.
   281  func (m *MachinePoolTopologyBuilder) WithVariables(variables ...clusterv1.ClusterVariable) *MachinePoolTopologyBuilder {
   282  	m.variables = variables
   283  	return m
   284  }
   285  
   286  // Build returns a testable MachinePoolTopology with any values passed to the builder.
   287  func (m *MachinePoolTopologyBuilder) Build() clusterv1.MachinePoolTopology {
   288  	mp := clusterv1.MachinePoolTopology{
   289  		Class:          m.class,
   290  		Name:           m.name,
   291  		Replicas:       m.replicas,
   292  		FailureDomains: m.failureDomains,
   293  	}
   294  
   295  	if len(m.variables) > 0 {
   296  		mp.Variables = &clusterv1.MachinePoolVariables{
   297  			Overrides: m.variables,
   298  		}
   299  	}
   300  
   301  	return mp
   302  }
   303  
   304  // ClusterClassBuilder holds the variables and objects required to build a clusterv1.ClusterClass.
   305  type ClusterClassBuilder struct {
   306  	namespace                                 string
   307  	name                                      string
   308  	infrastructureClusterTemplate             *unstructured.Unstructured
   309  	controlPlaneMetadata                      *clusterv1.ObjectMeta
   310  	controlPlaneTemplate                      *unstructured.Unstructured
   311  	controlPlaneInfrastructureMachineTemplate *unstructured.Unstructured
   312  	controlPlaneMHC                           *clusterv1.MachineHealthCheckClass
   313  	controlPlaneNodeDrainTimeout              *metav1.Duration
   314  	controlPlaneNodeVolumeDetachTimeout       *metav1.Duration
   315  	controlPlaneNodeDeletionTimeout           *metav1.Duration
   316  	controlPlaneNamingStrategy                *clusterv1.ControlPlaneClassNamingStrategy
   317  	machineDeploymentClasses                  []clusterv1.MachineDeploymentClass
   318  	machinePoolClasses                        []clusterv1.MachinePoolClass
   319  	variables                                 []clusterv1.ClusterClassVariable
   320  	statusVariables                           []clusterv1.ClusterClassStatusVariable
   321  	patches                                   []clusterv1.ClusterClassPatch
   322  }
   323  
   324  // ClusterClass returns a ClusterClassBuilder with the given name and namespace.
   325  func ClusterClass(namespace, name string) *ClusterClassBuilder {
   326  	return &ClusterClassBuilder{
   327  		namespace: namespace,
   328  		name:      name,
   329  	}
   330  }
   331  
   332  // WithInfrastructureClusterTemplate adds the passed InfrastructureClusterTemplate to the ClusterClassBuilder.
   333  func (c *ClusterClassBuilder) WithInfrastructureClusterTemplate(t *unstructured.Unstructured) *ClusterClassBuilder {
   334  	c.infrastructureClusterTemplate = t
   335  	return c
   336  }
   337  
   338  // WithControlPlaneTemplate adds the passed ControlPlaneTemplate to the ClusterClassBuilder.
   339  func (c *ClusterClassBuilder) WithControlPlaneTemplate(t *unstructured.Unstructured) *ClusterClassBuilder {
   340  	c.controlPlaneTemplate = t
   341  	return c
   342  }
   343  
   344  // WithControlPlaneMetadata adds the given labels and annotations for use with the ControlPlane to the ClusterClassBuilder.
   345  func (c *ClusterClassBuilder) WithControlPlaneMetadata(labels, annotations map[string]string) *ClusterClassBuilder {
   346  	c.controlPlaneMetadata = &clusterv1.ObjectMeta{
   347  		Labels:      labels,
   348  		Annotations: annotations,
   349  	}
   350  	return c
   351  }
   352  
   353  // WithControlPlaneInfrastructureMachineTemplate adds the ControlPlane's InfrastructureMachineTemplate to the ClusterClassBuilder.
   354  func (c *ClusterClassBuilder) WithControlPlaneInfrastructureMachineTemplate(t *unstructured.Unstructured) *ClusterClassBuilder {
   355  	c.controlPlaneInfrastructureMachineTemplate = t
   356  	return c
   357  }
   358  
   359  // WithControlPlaneMachineHealthCheck adds a MachineHealthCheck for the ControlPlane to the ClusterClassBuilder.
   360  func (c *ClusterClassBuilder) WithControlPlaneMachineHealthCheck(mhc *clusterv1.MachineHealthCheckClass) *ClusterClassBuilder {
   361  	c.controlPlaneMHC = mhc
   362  	return c
   363  }
   364  
   365  // WithControlPlaneNodeDrainTimeout adds a NodeDrainTimeout for the ControlPlane to the ClusterClassBuilder.
   366  func (c *ClusterClassBuilder) WithControlPlaneNodeDrainTimeout(t *metav1.Duration) *ClusterClassBuilder {
   367  	c.controlPlaneNodeDrainTimeout = t
   368  	return c
   369  }
   370  
   371  // WithControlPlaneNodeVolumeDetachTimeout adds a NodeVolumeDetachTimeout for the ControlPlane to the ClusterClassBuilder.
   372  func (c *ClusterClassBuilder) WithControlPlaneNodeVolumeDetachTimeout(t *metav1.Duration) *ClusterClassBuilder {
   373  	c.controlPlaneNodeVolumeDetachTimeout = t
   374  	return c
   375  }
   376  
   377  // WithControlPlaneNodeDeletionTimeout adds a NodeDeletionTimeout for the ControlPlane to the ClusterClassBuilder.
   378  func (c *ClusterClassBuilder) WithControlPlaneNodeDeletionTimeout(t *metav1.Duration) *ClusterClassBuilder {
   379  	c.controlPlaneNodeDeletionTimeout = t
   380  	return c
   381  }
   382  
   383  // WithControlPlaneNamingStrategy sets the NamingStrategy for the ControlPlane to the ClusterClassBuilder.
   384  func (c *ClusterClassBuilder) WithControlPlaneNamingStrategy(n *clusterv1.ControlPlaneClassNamingStrategy) *ClusterClassBuilder {
   385  	c.controlPlaneNamingStrategy = n
   386  	return c
   387  }
   388  
   389  // WithVariables adds the Variables to the ClusterClassBuilder.
   390  func (c *ClusterClassBuilder) WithVariables(vars ...clusterv1.ClusterClassVariable) *ClusterClassBuilder {
   391  	c.variables = vars
   392  	return c
   393  }
   394  
   395  // WithStatusVariables adds the ClusterClassStatusVariables to the ClusterClassBuilder.
   396  func (c *ClusterClassBuilder) WithStatusVariables(vars ...clusterv1.ClusterClassStatusVariable) *ClusterClassBuilder {
   397  	c.statusVariables = vars
   398  	return c
   399  }
   400  
   401  // WithPatches adds the patches to the ClusterClassBuilder.
   402  func (c *ClusterClassBuilder) WithPatches(patches []clusterv1.ClusterClassPatch) *ClusterClassBuilder {
   403  	c.patches = patches
   404  	return c
   405  }
   406  
   407  // WithWorkerMachineDeploymentClasses adds the variables and objects needed to create MachineDeploymentTemplates for a ClusterClassBuilder.
   408  func (c *ClusterClassBuilder) WithWorkerMachineDeploymentClasses(mdcs ...clusterv1.MachineDeploymentClass) *ClusterClassBuilder {
   409  	if c.machineDeploymentClasses == nil {
   410  		c.machineDeploymentClasses = make([]clusterv1.MachineDeploymentClass, 0)
   411  	}
   412  	c.machineDeploymentClasses = append(c.machineDeploymentClasses, mdcs...)
   413  	return c
   414  }
   415  
   416  // WithWorkerMachinePoolClasses adds the variables and objects needed to create MachinePoolTemplates for a ClusterClassBuilder.
   417  func (c *ClusterClassBuilder) WithWorkerMachinePoolClasses(mpcs ...clusterv1.MachinePoolClass) *ClusterClassBuilder {
   418  	if c.machinePoolClasses == nil {
   419  		c.machinePoolClasses = make([]clusterv1.MachinePoolClass, 0)
   420  	}
   421  	c.machinePoolClasses = append(c.machinePoolClasses, mpcs...)
   422  	return c
   423  }
   424  
   425  // Build takes the objects and variables in the ClusterClass builder and uses them to create a ClusterClass object.
   426  func (c *ClusterClassBuilder) Build() *clusterv1.ClusterClass {
   427  	obj := &clusterv1.ClusterClass{
   428  		TypeMeta: metav1.TypeMeta{
   429  			Kind:       "ClusterClass",
   430  			APIVersion: clusterv1.GroupVersion.String(),
   431  		},
   432  		ObjectMeta: metav1.ObjectMeta{
   433  			Name:      c.name,
   434  			Namespace: c.namespace,
   435  		},
   436  		Spec: clusterv1.ClusterClassSpec{
   437  			Variables: c.variables,
   438  			Patches:   c.patches,
   439  		},
   440  		Status: clusterv1.ClusterClassStatus{
   441  			Variables: c.statusVariables,
   442  		},
   443  	}
   444  	if c.infrastructureClusterTemplate != nil {
   445  		obj.Spec.Infrastructure = clusterv1.LocalObjectTemplate{
   446  			Ref: objToRef(c.infrastructureClusterTemplate),
   447  		}
   448  	}
   449  	if c.controlPlaneMetadata != nil {
   450  		obj.Spec.ControlPlane.Metadata = *c.controlPlaneMetadata
   451  	}
   452  	if c.controlPlaneTemplate != nil {
   453  		obj.Spec.ControlPlane.LocalObjectTemplate = clusterv1.LocalObjectTemplate{
   454  			Ref: objToRef(c.controlPlaneTemplate),
   455  		}
   456  	}
   457  	if c.controlPlaneMHC != nil {
   458  		obj.Spec.ControlPlane.MachineHealthCheck = c.controlPlaneMHC
   459  	}
   460  	if c.controlPlaneNodeDrainTimeout != nil {
   461  		obj.Spec.ControlPlane.NodeDrainTimeout = c.controlPlaneNodeDrainTimeout
   462  	}
   463  	if c.controlPlaneNodeVolumeDetachTimeout != nil {
   464  		obj.Spec.ControlPlane.NodeVolumeDetachTimeout = c.controlPlaneNodeVolumeDetachTimeout
   465  	}
   466  	if c.controlPlaneNodeDeletionTimeout != nil {
   467  		obj.Spec.ControlPlane.NodeDeletionTimeout = c.controlPlaneNodeDeletionTimeout
   468  	}
   469  	if c.controlPlaneInfrastructureMachineTemplate != nil {
   470  		obj.Spec.ControlPlane.MachineInfrastructure = &clusterv1.LocalObjectTemplate{
   471  			Ref: objToRef(c.controlPlaneInfrastructureMachineTemplate),
   472  		}
   473  	}
   474  	if c.controlPlaneNamingStrategy != nil {
   475  		obj.Spec.ControlPlane.NamingStrategy = c.controlPlaneNamingStrategy
   476  	}
   477  
   478  	obj.Spec.Workers.MachineDeployments = c.machineDeploymentClasses
   479  	obj.Spec.Workers.MachinePools = c.machinePoolClasses
   480  	return obj
   481  }
   482  
   483  // MachineDeploymentClassBuilder holds the variables and objects required to build a clusterv1.MachineDeploymentClass.
   484  type MachineDeploymentClassBuilder struct {
   485  	class                         string
   486  	infrastructureMachineTemplate *unstructured.Unstructured
   487  	bootstrapTemplate             *unstructured.Unstructured
   488  	labels                        map[string]string
   489  	annotations                   map[string]string
   490  	machineHealthCheckClass       *clusterv1.MachineHealthCheckClass
   491  	failureDomain                 *string
   492  	nodeDrainTimeout              *metav1.Duration
   493  	nodeVolumeDetachTimeout       *metav1.Duration
   494  	nodeDeletionTimeout           *metav1.Duration
   495  	minReadySeconds               *int32
   496  	strategy                      *clusterv1.MachineDeploymentStrategy
   497  	namingStrategy                *clusterv1.MachineDeploymentClassNamingStrategy
   498  }
   499  
   500  // MachineDeploymentClass returns a MachineDeploymentClassBuilder with the given name and namespace.
   501  func MachineDeploymentClass(class string) *MachineDeploymentClassBuilder {
   502  	return &MachineDeploymentClassBuilder{
   503  		class: class,
   504  	}
   505  }
   506  
   507  // WithInfrastructureTemplate registers the passed Unstructured object as the InfrastructureMachineTemplate for the MachineDeploymentClassBuilder.
   508  func (m *MachineDeploymentClassBuilder) WithInfrastructureTemplate(t *unstructured.Unstructured) *MachineDeploymentClassBuilder {
   509  	m.infrastructureMachineTemplate = t
   510  	return m
   511  }
   512  
   513  // WithBootstrapTemplate registers the passed Unstructured object as the BootstrapTemplate for the MachineDeploymentClassBuilder.
   514  func (m *MachineDeploymentClassBuilder) WithBootstrapTemplate(t *unstructured.Unstructured) *MachineDeploymentClassBuilder {
   515  	m.bootstrapTemplate = t
   516  	return m
   517  }
   518  
   519  // WithLabels sets the labels for the MachineDeploymentClassBuilder.
   520  func (m *MachineDeploymentClassBuilder) WithLabels(labels map[string]string) *MachineDeploymentClassBuilder {
   521  	m.labels = labels
   522  	return m
   523  }
   524  
   525  // WithAnnotations sets the annotations for the MachineDeploymentClassBuilder.
   526  func (m *MachineDeploymentClassBuilder) WithAnnotations(annotations map[string]string) *MachineDeploymentClassBuilder {
   527  	m.annotations = annotations
   528  	return m
   529  }
   530  
   531  // WithMachineHealthCheckClass sets the MachineHealthCheckClass for the MachineDeploymentClassBuilder.
   532  func (m *MachineDeploymentClassBuilder) WithMachineHealthCheckClass(mhc *clusterv1.MachineHealthCheckClass) *MachineDeploymentClassBuilder {
   533  	m.machineHealthCheckClass = mhc
   534  	return m
   535  }
   536  
   537  // WithFailureDomain sets the FailureDomain for the MachineDeploymentClassBuilder.
   538  func (m *MachineDeploymentClassBuilder) WithFailureDomain(f *string) *MachineDeploymentClassBuilder {
   539  	m.failureDomain = f
   540  	return m
   541  }
   542  
   543  // WithNodeDrainTimeout sets the NodeDrainTimeout for the MachineDeploymentClassBuilder.
   544  func (m *MachineDeploymentClassBuilder) WithNodeDrainTimeout(t *metav1.Duration) *MachineDeploymentClassBuilder {
   545  	m.nodeDrainTimeout = t
   546  	return m
   547  }
   548  
   549  // WithNodeVolumeDetachTimeout sets the NodeVolumeDetachTimeout for the MachineDeploymentClassBuilder.
   550  func (m *MachineDeploymentClassBuilder) WithNodeVolumeDetachTimeout(t *metav1.Duration) *MachineDeploymentClassBuilder {
   551  	m.nodeVolumeDetachTimeout = t
   552  	return m
   553  }
   554  
   555  // WithNodeDeletionTimeout sets the NodeDeletionTimeout for the MachineDeploymentClassBuilder.
   556  func (m *MachineDeploymentClassBuilder) WithNodeDeletionTimeout(t *metav1.Duration) *MachineDeploymentClassBuilder {
   557  	m.nodeDeletionTimeout = t
   558  	return m
   559  }
   560  
   561  // WithMinReadySeconds sets the MinReadySeconds for the MachineDeploymentClassBuilder.
   562  func (m *MachineDeploymentClassBuilder) WithMinReadySeconds(t *int32) *MachineDeploymentClassBuilder {
   563  	m.minReadySeconds = t
   564  	return m
   565  }
   566  
   567  // WithStrategy sets the Strategy for the MachineDeploymentClassBuilder.
   568  func (m *MachineDeploymentClassBuilder) WithStrategy(s *clusterv1.MachineDeploymentStrategy) *MachineDeploymentClassBuilder {
   569  	m.strategy = s
   570  	return m
   571  }
   572  
   573  // WithNamingStrategy sets the NamingStrategy for the MachineDeploymentClassBuilder.
   574  func (m *MachineDeploymentClassBuilder) WithNamingStrategy(n *clusterv1.MachineDeploymentClassNamingStrategy) *MachineDeploymentClassBuilder {
   575  	m.namingStrategy = n
   576  	return m
   577  }
   578  
   579  // Build creates a full MachineDeploymentClass object with the variables passed to the MachineDeploymentClassBuilder.
   580  func (m *MachineDeploymentClassBuilder) Build() *clusterv1.MachineDeploymentClass {
   581  	obj := &clusterv1.MachineDeploymentClass{
   582  		Class: m.class,
   583  		Template: clusterv1.MachineDeploymentClassTemplate{
   584  			Metadata: clusterv1.ObjectMeta{
   585  				Labels:      m.labels,
   586  				Annotations: m.annotations,
   587  			},
   588  		},
   589  	}
   590  	if m.bootstrapTemplate != nil {
   591  		obj.Template.Bootstrap.Ref = objToRef(m.bootstrapTemplate)
   592  	}
   593  	if m.infrastructureMachineTemplate != nil {
   594  		obj.Template.Infrastructure.Ref = objToRef(m.infrastructureMachineTemplate)
   595  	}
   596  	if m.machineHealthCheckClass != nil {
   597  		obj.MachineHealthCheck = m.machineHealthCheckClass
   598  	}
   599  	if m.failureDomain != nil {
   600  		obj.FailureDomain = m.failureDomain
   601  	}
   602  	if m.nodeDrainTimeout != nil {
   603  		obj.NodeDrainTimeout = m.nodeDrainTimeout
   604  	}
   605  	if m.nodeVolumeDetachTimeout != nil {
   606  		obj.NodeVolumeDetachTimeout = m.nodeVolumeDetachTimeout
   607  	}
   608  	if m.nodeDeletionTimeout != nil {
   609  		obj.NodeDeletionTimeout = m.nodeDeletionTimeout
   610  	}
   611  	if m.minReadySeconds != nil {
   612  		obj.MinReadySeconds = m.minReadySeconds
   613  	}
   614  	if m.strategy != nil {
   615  		obj.Strategy = m.strategy
   616  	}
   617  	if m.namingStrategy != nil {
   618  		obj.NamingStrategy = m.namingStrategy
   619  	}
   620  	return obj
   621  }
   622  
   623  // MachinePoolClassBuilder holds the variables and objects required to build a clusterv1.MachinePoolClass.
   624  type MachinePoolClassBuilder struct {
   625  	class                             string
   626  	infrastructureMachinePoolTemplate *unstructured.Unstructured
   627  	bootstrapTemplate                 *unstructured.Unstructured
   628  	labels                            map[string]string
   629  	annotations                       map[string]string
   630  	failureDomains                    []string
   631  	nodeDrainTimeout                  *metav1.Duration
   632  	nodeVolumeDetachTimeout           *metav1.Duration
   633  	nodeDeletionTimeout               *metav1.Duration
   634  	minReadySeconds                   *int32
   635  	namingStrategy                    *clusterv1.MachinePoolClassNamingStrategy
   636  }
   637  
   638  // MachinePoolClass returns a MachinePoolClassBuilder with the given name and namespace.
   639  func MachinePoolClass(class string) *MachinePoolClassBuilder {
   640  	return &MachinePoolClassBuilder{
   641  		class: class,
   642  	}
   643  }
   644  
   645  // WithInfrastructureTemplate registers the passed Unstructured object as the InfrastructureMachinePoolTemplate for the MachinePoolClassBuilder.
   646  func (m *MachinePoolClassBuilder) WithInfrastructureTemplate(t *unstructured.Unstructured) *MachinePoolClassBuilder {
   647  	m.infrastructureMachinePoolTemplate = t
   648  	return m
   649  }
   650  
   651  // WithBootstrapTemplate registers the passed Unstructured object as the BootstrapTemplate for the MachinePoolClassBuilder.
   652  func (m *MachinePoolClassBuilder) WithBootstrapTemplate(t *unstructured.Unstructured) *MachinePoolClassBuilder {
   653  	m.bootstrapTemplate = t
   654  	return m
   655  }
   656  
   657  // WithLabels sets the labels for the MachinePoolClassBuilder.
   658  func (m *MachinePoolClassBuilder) WithLabels(labels map[string]string) *MachinePoolClassBuilder {
   659  	m.labels = labels
   660  	return m
   661  }
   662  
   663  // WithAnnotations sets the annotations for the MachinePoolClassBuilder.
   664  func (m *MachinePoolClassBuilder) WithAnnotations(annotations map[string]string) *MachinePoolClassBuilder {
   665  	m.annotations = annotations
   666  	return m
   667  }
   668  
   669  // WithFailureDomains sets the FailureDomains for the MachinePoolClassBuilder.
   670  func (m *MachinePoolClassBuilder) WithFailureDomains(failureDomains ...string) *MachinePoolClassBuilder {
   671  	m.failureDomains = failureDomains
   672  	return m
   673  }
   674  
   675  // WithNodeDrainTimeout sets the NodeDrainTimeout for the MachinePoolClassBuilder.
   676  func (m *MachinePoolClassBuilder) WithNodeDrainTimeout(t *metav1.Duration) *MachinePoolClassBuilder {
   677  	m.nodeDrainTimeout = t
   678  	return m
   679  }
   680  
   681  // WithNodeVolumeDetachTimeout sets the NodeVolumeDetachTimeout for the MachinePoolClassBuilder.
   682  func (m *MachinePoolClassBuilder) WithNodeVolumeDetachTimeout(t *metav1.Duration) *MachinePoolClassBuilder {
   683  	m.nodeVolumeDetachTimeout = t
   684  	return m
   685  }
   686  
   687  // WithNodeDeletionTimeout sets the NodeDeletionTimeout for the MachinePoolClassBuilder.
   688  func (m *MachinePoolClassBuilder) WithNodeDeletionTimeout(t *metav1.Duration) *MachinePoolClassBuilder {
   689  	m.nodeDeletionTimeout = t
   690  	return m
   691  }
   692  
   693  // WithMinReadySeconds sets the MinReadySeconds for the MachinePoolClassBuilder.
   694  func (m *MachinePoolClassBuilder) WithMinReadySeconds(t *int32) *MachinePoolClassBuilder {
   695  	m.minReadySeconds = t
   696  	return m
   697  }
   698  
   699  // WithNamingStrategy sets the NamingStrategy for the MachinePoolClassBuilder.
   700  func (m *MachinePoolClassBuilder) WithNamingStrategy(n *clusterv1.MachinePoolClassNamingStrategy) *MachinePoolClassBuilder {
   701  	m.namingStrategy = n
   702  	return m
   703  }
   704  
   705  // Build creates a full MachinePoolClass object with the variables passed to the MachinePoolClassBuilder.
   706  func (m *MachinePoolClassBuilder) Build() *clusterv1.MachinePoolClass {
   707  	obj := &clusterv1.MachinePoolClass{
   708  		Class: m.class,
   709  		Template: clusterv1.MachinePoolClassTemplate{
   710  			Metadata: clusterv1.ObjectMeta{
   711  				Labels:      m.labels,
   712  				Annotations: m.annotations,
   713  			},
   714  		},
   715  	}
   716  	if m.bootstrapTemplate != nil {
   717  		obj.Template.Bootstrap.Ref = objToRef(m.bootstrapTemplate)
   718  	}
   719  	if m.infrastructureMachinePoolTemplate != nil {
   720  		obj.Template.Infrastructure.Ref = objToRef(m.infrastructureMachinePoolTemplate)
   721  	}
   722  	if m.failureDomains != nil {
   723  		obj.FailureDomains = m.failureDomains
   724  	}
   725  	if m.nodeDrainTimeout != nil {
   726  		obj.NodeDrainTimeout = m.nodeDrainTimeout
   727  	}
   728  	if m.nodeVolumeDetachTimeout != nil {
   729  		obj.NodeVolumeDetachTimeout = m.nodeVolumeDetachTimeout
   730  	}
   731  	if m.nodeDeletionTimeout != nil {
   732  		obj.NodeDeletionTimeout = m.nodeDeletionTimeout
   733  	}
   734  	if m.minReadySeconds != nil {
   735  		obj.MinReadySeconds = m.minReadySeconds
   736  	}
   737  	if m.namingStrategy != nil {
   738  		obj.NamingStrategy = m.namingStrategy
   739  	}
   740  	return obj
   741  }
   742  
   743  // InfrastructureMachineTemplateBuilder holds the variables and objects needed to build an InfrastructureMachineTemplate.
   744  type InfrastructureMachineTemplateBuilder struct {
   745  	obj *unstructured.Unstructured
   746  }
   747  
   748  // InfrastructureMachineTemplate creates an InfrastructureMachineTemplateBuilder with the given name and namespace.
   749  func InfrastructureMachineTemplate(namespace, name string) *InfrastructureMachineTemplateBuilder {
   750  	obj := &unstructured.Unstructured{}
   751  	obj.SetName(name)
   752  	obj.SetNamespace(namespace)
   753  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
   754  	obj.SetKind(GenericInfrastructureMachineTemplateKind)
   755  	// Set the mandatory spec fields for the object.
   756  	setSpecFields(obj, map[string]interface{}{"spec.template.spec": map[string]interface{}{}})
   757  	return &InfrastructureMachineTemplateBuilder{
   758  		obj,
   759  	}
   760  }
   761  
   762  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
   763  // to the value of the spec field.
   764  //
   765  // Note: all the paths should start with "spec."
   766  //
   767  //	Example map: map[string]interface{}{
   768  //	    "spec.version": "v1.2.3",
   769  //	}.
   770  func (i *InfrastructureMachineTemplateBuilder) WithSpecFields(fields map[string]interface{}) *InfrastructureMachineTemplateBuilder {
   771  	setSpecFields(i.obj, fields)
   772  	return i
   773  }
   774  
   775  // Build takes the objects and variables in the  InfrastructureMachineTemplateBuilder and generates an unstructured object.
   776  func (i *InfrastructureMachineTemplateBuilder) Build() *unstructured.Unstructured {
   777  	return i.obj
   778  }
   779  
   780  // TestInfrastructureMachineTemplateBuilder holds the variables and objects needed to build an TestInfrastructureMachineTemplate.
   781  type TestInfrastructureMachineTemplateBuilder struct {
   782  	obj *unstructured.Unstructured
   783  }
   784  
   785  // TestInfrastructureMachineTemplate creates an TestInfrastructureMachineTemplateBuilder with the given name and namespace.
   786  func TestInfrastructureMachineTemplate(namespace, name string) *TestInfrastructureMachineTemplateBuilder {
   787  	obj := &unstructured.Unstructured{}
   788  	obj.SetName(name)
   789  	obj.SetNamespace(namespace)
   790  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
   791  	obj.SetKind(TestInfrastructureMachineTemplateKind)
   792  	// Set the mandatory spec fields for the object.
   793  	if err := unstructured.SetNestedField(obj.Object, map[string]interface{}{}, "spec", "template", "spec"); err != nil {
   794  		panic(err)
   795  	}
   796  	return &TestInfrastructureMachineTemplateBuilder{
   797  		obj,
   798  	}
   799  }
   800  
   801  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
   802  // to the value of the spec field.
   803  //
   804  // Note: all the paths should start with "spec."; the path should correspond to a field defined in the CRD.
   805  //
   806  //	Example map: map[string]interface{}{
   807  //	    "spec.version": "v1.2.3",
   808  //	}.
   809  func (i *TestInfrastructureMachineTemplateBuilder) WithSpecFields(fields map[string]interface{}) *TestInfrastructureMachineTemplateBuilder {
   810  	setSpecFields(i.obj, fields)
   811  	return i
   812  }
   813  
   814  // Build takes the objects and variables in the  InfrastructureMachineTemplateBuilder and generates an unstructured object.
   815  func (i *TestInfrastructureMachineTemplateBuilder) Build() *unstructured.Unstructured {
   816  	return i.obj
   817  }
   818  
   819  // InfrastructureMachinePoolTemplateBuilder holds the variables and objects needed to build an InfrastructureMachinePoolTemplate.
   820  type InfrastructureMachinePoolTemplateBuilder struct {
   821  	obj *unstructured.Unstructured
   822  }
   823  
   824  // InfrastructureMachinePoolTemplate creates an InfrastructureMachinePoolTemplateBuilder with the given name and namespace.
   825  func InfrastructureMachinePoolTemplate(namespace, name string) *InfrastructureMachinePoolTemplateBuilder {
   826  	obj := &unstructured.Unstructured{}
   827  	obj.SetName(name)
   828  	obj.SetNamespace(namespace)
   829  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
   830  	obj.SetKind(GenericInfrastructureMachinePoolTemplateKind)
   831  	// Set the mandatory spec fields for the object.
   832  	setSpecFields(obj, map[string]interface{}{"spec.template.spec": map[string]interface{}{}})
   833  	return &InfrastructureMachinePoolTemplateBuilder{
   834  		obj,
   835  	}
   836  }
   837  
   838  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
   839  // to the value of the spec field.
   840  //
   841  // Note: all the paths should start with "spec."
   842  //
   843  //	Example map: map[string]interface{}{
   844  //	    "spec.version": "v1.2.3",
   845  //	}.
   846  func (i *InfrastructureMachinePoolTemplateBuilder) WithSpecFields(fields map[string]interface{}) *InfrastructureMachinePoolTemplateBuilder {
   847  	setSpecFields(i.obj, fields)
   848  	return i
   849  }
   850  
   851  // Build takes the objects and variables in the  InfrastructureMachineTemplateBuilder and generates an unstructured object.
   852  func (i *InfrastructureMachinePoolTemplateBuilder) Build() *unstructured.Unstructured {
   853  	return i.obj
   854  }
   855  
   856  // TestInfrastructureMachinePoolTemplateBuilder holds the variables and objects needed to build an TestInfrastructureMachinePoolTemplate.
   857  type TestInfrastructureMachinePoolTemplateBuilder struct {
   858  	obj *unstructured.Unstructured
   859  }
   860  
   861  // TestInfrastructureMachinePoolTemplate creates an TestInfrastructureMachinePoolTemplateBuilder with the given name and namespace.
   862  func TestInfrastructureMachinePoolTemplate(namespace, name string) *TestInfrastructureMachinePoolTemplateBuilder {
   863  	obj := &unstructured.Unstructured{}
   864  	obj.SetName(name)
   865  	obj.SetNamespace(namespace)
   866  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
   867  	obj.SetKind(TestInfrastructureMachinePoolTemplateKind)
   868  	// Set the mandatory spec fields for the object.
   869  	if err := unstructured.SetNestedField(obj.Object, map[string]interface{}{}, "spec", "template", "spec"); err != nil {
   870  		panic(err)
   871  	}
   872  	return &TestInfrastructureMachinePoolTemplateBuilder{
   873  		obj,
   874  	}
   875  }
   876  
   877  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
   878  // to the value of the spec field.
   879  //
   880  // Note: all the paths should start with "spec."; the path should correspond to a field defined in the CRD.
   881  //
   882  //	Example map: map[string]interface{}{
   883  //	    "spec.version": "v1.2.3",
   884  //	}.
   885  func (i *TestInfrastructureMachinePoolTemplateBuilder) WithSpecFields(fields map[string]interface{}) *TestInfrastructureMachinePoolTemplateBuilder {
   886  	setSpecFields(i.obj, fields)
   887  	return i
   888  }
   889  
   890  // Build takes the objects and variables in the TestInfrastructureMachineTemplateBuilder and generates an unstructured object.
   891  func (i *TestInfrastructureMachinePoolTemplateBuilder) Build() *unstructured.Unstructured {
   892  	return i.obj
   893  }
   894  
   895  // InfrastructureMachinePoolBuilder holds the variables and objects needed to build an InfrastructureMachinePool.
   896  type InfrastructureMachinePoolBuilder struct {
   897  	obj *unstructured.Unstructured
   898  }
   899  
   900  // InfrastructureMachinePool creates an InfrastructureMachinePoolBuilder with the given name and namespace.
   901  func InfrastructureMachinePool(namespace, name string) *InfrastructureMachinePoolBuilder {
   902  	obj := &unstructured.Unstructured{}
   903  	obj.SetName(name)
   904  	obj.SetNamespace(namespace)
   905  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
   906  	obj.SetKind(GenericInfrastructureMachinePoolKind)
   907  	// Set the mandatory spec fields for the object.
   908  	setSpecFields(obj, map[string]interface{}{"spec": map[string]interface{}{}})
   909  	return &InfrastructureMachinePoolBuilder{
   910  		obj,
   911  	}
   912  }
   913  
   914  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
   915  // to the value of the spec field.
   916  //
   917  // Note: all the paths should start with "spec."
   918  //
   919  //	Example map: map[string]interface{}{
   920  //	    "spec.version": "v1.2.3",
   921  //	}.
   922  func (i *InfrastructureMachinePoolBuilder) WithSpecFields(fields map[string]interface{}) *InfrastructureMachinePoolBuilder {
   923  	setSpecFields(i.obj, fields)
   924  	return i
   925  }
   926  
   927  // Build takes the objects and variables in the InfrastructureMachinePoolBuilder and generates an unstructured object.
   928  func (i *InfrastructureMachinePoolBuilder) Build() *unstructured.Unstructured {
   929  	return i.obj
   930  }
   931  
   932  // TestInfrastructureMachinePoolBuilder holds the variables and objects needed to build an TestInfrastructureMachinePool.
   933  type TestInfrastructureMachinePoolBuilder struct {
   934  	obj *unstructured.Unstructured
   935  }
   936  
   937  // TestInfrastructureMachinePool creates an TestInfrastructureMachinePoolBuilder with the given name and namespace.
   938  func TestInfrastructureMachinePool(namespace, name string) *TestInfrastructureMachinePoolBuilder {
   939  	obj := &unstructured.Unstructured{}
   940  	obj.SetName(name)
   941  	obj.SetNamespace(namespace)
   942  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
   943  	obj.SetKind(TestInfrastructureMachinePoolKind)
   944  	// Set the mandatory spec fields for the object.
   945  	if err := unstructured.SetNestedField(obj.Object, map[string]interface{}{}, "spec"); err != nil {
   946  		panic(err)
   947  	}
   948  	return &TestInfrastructureMachinePoolBuilder{
   949  		obj,
   950  	}
   951  }
   952  
   953  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
   954  // to the value of the spec field.
   955  //
   956  // Note: all the paths should start with "spec."; the path should correspond to a field defined in the CRD.
   957  //
   958  //	Example map: map[string]interface{}{
   959  //	    "spec.version": "v1.2.3",
   960  //	}.
   961  func (i *TestInfrastructureMachinePoolBuilder) WithSpecFields(fields map[string]interface{}) *TestInfrastructureMachinePoolBuilder {
   962  	setSpecFields(i.obj, fields)
   963  	return i
   964  }
   965  
   966  // Build takes the objects and variables in the TestInfrastructureMachinePoolBuilder and generates an unstructured object.
   967  func (i *TestInfrastructureMachinePoolBuilder) Build() *unstructured.Unstructured {
   968  	return i.obj
   969  }
   970  
   971  // BootstrapTemplateBuilder holds the variables needed to build a generic BootstrapTemplate.
   972  type BootstrapTemplateBuilder struct {
   973  	obj *unstructured.Unstructured
   974  }
   975  
   976  // BootstrapTemplate creates a BootstrapTemplateBuilder with the given name and namespace.
   977  func BootstrapTemplate(namespace, name string) *BootstrapTemplateBuilder {
   978  	obj := &unstructured.Unstructured{}
   979  	obj.SetAPIVersion(BootstrapGroupVersion.String())
   980  	obj.SetKind(GenericBootstrapConfigTemplateKind)
   981  	obj.SetNamespace(namespace)
   982  	obj.SetName(name)
   983  	setSpecFields(obj, map[string]interface{}{"spec.template.spec": map[string]interface{}{}})
   984  
   985  	return &BootstrapTemplateBuilder{obj: obj}
   986  }
   987  
   988  // WithSpecFields will add fields of any type to the object spec. It takes an argument, fields, which is of the form path: object.
   989  func (b *BootstrapTemplateBuilder) WithSpecFields(fields map[string]interface{}) *BootstrapTemplateBuilder {
   990  	setSpecFields(b.obj, fields)
   991  	return b
   992  }
   993  
   994  // Build creates a new Unstructured object with the information passed to the BootstrapTemplateBuilder.
   995  func (b *BootstrapTemplateBuilder) Build() *unstructured.Unstructured {
   996  	return b.obj
   997  }
   998  
   999  // TestBootstrapTemplateBuilder holds the variables needed to build a generic TestBootstrapTemplate.
  1000  type TestBootstrapTemplateBuilder struct {
  1001  	obj *unstructured.Unstructured
  1002  }
  1003  
  1004  // TestBootstrapTemplate creates a TestBootstrapTemplateBuilder with the given name and namespace.
  1005  func TestBootstrapTemplate(namespace, name string) *TestBootstrapTemplateBuilder {
  1006  	obj := &unstructured.Unstructured{}
  1007  	obj.SetAPIVersion(BootstrapGroupVersion.String())
  1008  	obj.SetKind(TestBootstrapConfigTemplateKind)
  1009  	obj.SetNamespace(namespace)
  1010  	obj.SetName(name)
  1011  	setSpecFields(obj, map[string]interface{}{"spec.template.spec": map[string]interface{}{}})
  1012  
  1013  	return &TestBootstrapTemplateBuilder{
  1014  		obj: obj,
  1015  	}
  1016  }
  1017  
  1018  // WithSpecFields will add fields of any type to the object spec. It takes an argument, fields, which is of the form path: object.
  1019  // NOTE: The path should correspond to a field defined in the CRD.
  1020  func (b *TestBootstrapTemplateBuilder) WithSpecFields(fields map[string]interface{}) *TestBootstrapTemplateBuilder {
  1021  	setSpecFields(b.obj, fields)
  1022  	return b
  1023  }
  1024  
  1025  // Build creates a new Unstructured object with the information passed to the BootstrapTemplateBuilder.
  1026  func (b *TestBootstrapTemplateBuilder) Build() *unstructured.Unstructured {
  1027  	return b.obj
  1028  }
  1029  
  1030  // BootstrapConfigBuilder holds the variables needed to build a generic BootstrapConfig.
  1031  type BootstrapConfigBuilder struct {
  1032  	obj *unstructured.Unstructured
  1033  }
  1034  
  1035  // BootstrapConfig creates a BootstrapConfigBuilder with the given name and namespace.
  1036  func BootstrapConfig(namespace, name string) *BootstrapConfigBuilder {
  1037  	obj := &unstructured.Unstructured{}
  1038  	obj.SetAPIVersion(BootstrapGroupVersion.String())
  1039  	obj.SetKind(GenericBootstrapConfigKind)
  1040  	obj.SetNamespace(namespace)
  1041  	obj.SetName(name)
  1042  	setSpecFields(obj, map[string]interface{}{"spec": map[string]interface{}{}})
  1043  
  1044  	return &BootstrapConfigBuilder{obj: obj}
  1045  }
  1046  
  1047  // WithSpecFields will add fields of any type to the object spec. It takes an argument, fields, which is of the form path: object.
  1048  func (b *BootstrapConfigBuilder) WithSpecFields(fields map[string]interface{}) *BootstrapConfigBuilder {
  1049  	setSpecFields(b.obj, fields)
  1050  	return b
  1051  }
  1052  
  1053  // Build creates a new Unstructured object with the information passed to the BootstrapConfigBuilder.
  1054  func (b *BootstrapConfigBuilder) Build() *unstructured.Unstructured {
  1055  	return b.obj
  1056  }
  1057  
  1058  // TestBootstrapConfigBuilder holds the variables needed to build a generic TestBootstrapConfig.
  1059  type TestBootstrapConfigBuilder struct {
  1060  	obj *unstructured.Unstructured
  1061  }
  1062  
  1063  // TestBootstrapConfig creates a TestBootstrapConfigBuilder with the given name and namespace.
  1064  func TestBootstrapConfig(namespace, name string) *TestBootstrapConfigBuilder {
  1065  	obj := &unstructured.Unstructured{}
  1066  	obj.SetAPIVersion(BootstrapGroupVersion.String())
  1067  	obj.SetKind(TestBootstrapConfigKind)
  1068  	obj.SetNamespace(namespace)
  1069  	obj.SetName(name)
  1070  	setSpecFields(obj, map[string]interface{}{"spec": map[string]interface{}{}})
  1071  
  1072  	return &TestBootstrapConfigBuilder{
  1073  		obj: obj,
  1074  	}
  1075  }
  1076  
  1077  // WithSpecFields will add fields of any type to the object spec. It takes an argument, fields, which is of the form path: object.
  1078  // NOTE: The path should correspond to a field defined in the CRD.
  1079  func (b *TestBootstrapConfigBuilder) WithSpecFields(fields map[string]interface{}) *TestBootstrapConfigBuilder {
  1080  	setSpecFields(b.obj, fields)
  1081  	return b
  1082  }
  1083  
  1084  // Build creates a new Unstructured object with the information passed to the BootstrapConfigBuilder.
  1085  func (b *TestBootstrapConfigBuilder) Build() *unstructured.Unstructured {
  1086  	return b.obj
  1087  }
  1088  
  1089  // InfrastructureClusterTemplateBuilder holds the variables needed to build a generic InfrastructureClusterTemplate.
  1090  type InfrastructureClusterTemplateBuilder struct {
  1091  	obj *unstructured.Unstructured
  1092  }
  1093  
  1094  // InfrastructureClusterTemplate returns an InfrastructureClusterTemplateBuilder with the given name and namespace.
  1095  func InfrastructureClusterTemplate(namespace, name string) *InfrastructureClusterTemplateBuilder {
  1096  	obj := &unstructured.Unstructured{}
  1097  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
  1098  	obj.SetKind(GenericInfrastructureClusterTemplateKind)
  1099  	obj.SetNamespace(namespace)
  1100  	obj.SetName(name)
  1101  	if err := unstructured.SetNestedField(obj.Object, map[string]interface{}{}, "spec", "template", "spec"); err != nil {
  1102  		panic(err)
  1103  	}
  1104  	return &InfrastructureClusterTemplateBuilder{
  1105  		obj: obj,
  1106  	}
  1107  }
  1108  
  1109  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1110  // to the value of the spec field.
  1111  //
  1112  // Note: all the paths should start with "spec."
  1113  //
  1114  //	Example map: map[string]interface{}{
  1115  //	    "spec.version": "v1.2.3",
  1116  //	}.
  1117  func (i *InfrastructureClusterTemplateBuilder) WithSpecFields(fields map[string]interface{}) *InfrastructureClusterTemplateBuilder {
  1118  	setSpecFields(i.obj, fields)
  1119  	return i
  1120  }
  1121  
  1122  // Build creates a new Unstructured object with the variables passed to the InfrastructureClusterTemplateBuilder.
  1123  func (i *InfrastructureClusterTemplateBuilder) Build() *unstructured.Unstructured {
  1124  	return i.obj
  1125  }
  1126  
  1127  // TestInfrastructureClusterTemplateBuilder holds the variables needed to build a generic TestInfrastructureClusterTemplate.
  1128  type TestInfrastructureClusterTemplateBuilder struct {
  1129  	obj *unstructured.Unstructured
  1130  }
  1131  
  1132  // TestInfrastructureClusterTemplate returns an TestInfrastructureClusterTemplateBuilder with the given name and namespace.
  1133  func TestInfrastructureClusterTemplate(namespace, name string) *TestInfrastructureClusterTemplateBuilder {
  1134  	obj := &unstructured.Unstructured{}
  1135  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
  1136  	obj.SetKind(TestInfrastructureClusterTemplateKind)
  1137  	obj.SetNamespace(namespace)
  1138  	obj.SetName(name)
  1139  	if err := unstructured.SetNestedField(obj.Object, map[string]interface{}{}, "spec", "template", "spec"); err != nil {
  1140  		panic(err)
  1141  	}
  1142  	return &TestInfrastructureClusterTemplateBuilder{
  1143  		obj: obj,
  1144  	}
  1145  }
  1146  
  1147  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1148  // to the value of the spec field.
  1149  //
  1150  // Note: all the paths should start with "spec."; the path should correspond to a field defined in the CRD.
  1151  //
  1152  //	Example map: map[string]interface{}{
  1153  //	    "spec.version": "v1.2.3",
  1154  //	}.
  1155  func (i *TestInfrastructureClusterTemplateBuilder) WithSpecFields(fields map[string]interface{}) *TestInfrastructureClusterTemplateBuilder {
  1156  	setSpecFields(i.obj, fields)
  1157  	return i
  1158  }
  1159  
  1160  // Build creates a new Unstructured object with the variables passed to the InfrastructureClusterTemplateBuilder.
  1161  func (i *TestInfrastructureClusterTemplateBuilder) Build() *unstructured.Unstructured {
  1162  	return i.obj
  1163  }
  1164  
  1165  // ControlPlaneTemplateBuilder holds the variables and objects needed to build a generic ControlPlane template.
  1166  type ControlPlaneTemplateBuilder struct {
  1167  	obj *unstructured.Unstructured
  1168  }
  1169  
  1170  // ControlPlaneTemplate creates a NewControlPlaneTemplate builder with the given name and namespace.
  1171  func ControlPlaneTemplate(namespace, name string) *ControlPlaneTemplateBuilder {
  1172  	obj := &unstructured.Unstructured{}
  1173  	obj.SetAPIVersion(ControlPlaneGroupVersion.String())
  1174  	obj.SetKind(GenericControlPlaneTemplateKind)
  1175  	obj.SetNamespace(namespace)
  1176  	obj.SetName(name)
  1177  
  1178  	// Initialize the spec.template.spec to make the object valid in reconciliation.
  1179  	setSpecFields(obj, map[string]interface{}{"spec.template.spec": map[string]interface{}{}})
  1180  	return &ControlPlaneTemplateBuilder{obj: obj}
  1181  }
  1182  
  1183  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1184  // to the value of the spec field.
  1185  //
  1186  // Note: all the paths should start with "spec."
  1187  //
  1188  //	Example map: map[string]interface{}{
  1189  //	    "spec.version": "v1.2.3",
  1190  //	}.
  1191  func (c *ControlPlaneTemplateBuilder) WithSpecFields(fields map[string]interface{}) *ControlPlaneTemplateBuilder {
  1192  	setSpecFields(c.obj, fields)
  1193  	return c
  1194  }
  1195  
  1196  // WithInfrastructureMachineTemplate adds the given Unstructured object to the ControlPlaneTemplateBuilder as its InfrastructureMachineTemplate.
  1197  func (c *ControlPlaneTemplateBuilder) WithInfrastructureMachineTemplate(t *unstructured.Unstructured) *ControlPlaneTemplateBuilder {
  1198  	if err := setNestedRef(c.obj, t, "spec", "template", "spec", "machineTemplate", "infrastructureRef"); err != nil {
  1199  		panic(err)
  1200  	}
  1201  	return c
  1202  }
  1203  
  1204  // Build creates an Unstructured object from the variables passed to the ControlPlaneTemplateBuilder.
  1205  func (c *ControlPlaneTemplateBuilder) Build() *unstructured.Unstructured {
  1206  	return c.obj
  1207  }
  1208  
  1209  // TestControlPlaneTemplateBuilder holds the variables and objects needed to build a generic ControlPlane template.
  1210  type TestControlPlaneTemplateBuilder struct {
  1211  	obj *unstructured.Unstructured
  1212  }
  1213  
  1214  // TestControlPlaneTemplate creates a NewControlPlaneTemplate builder with the given name and namespace.
  1215  func TestControlPlaneTemplate(namespace, name string) *TestControlPlaneTemplateBuilder {
  1216  	obj := &unstructured.Unstructured{}
  1217  	obj.SetName(name)
  1218  	obj.SetNamespace(namespace)
  1219  	obj.SetAPIVersion(ControlPlaneGroupVersion.String())
  1220  	obj.SetKind(TestControlPlaneTemplateKind)
  1221  	// Set the mandatory spec field for the object.
  1222  	if err := unstructured.SetNestedField(obj.Object, map[string]interface{}{}, "spec", "template", "spec"); err != nil {
  1223  		panic(err)
  1224  	}
  1225  	return &TestControlPlaneTemplateBuilder{
  1226  		obj,
  1227  	}
  1228  }
  1229  
  1230  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1231  // to the value of the spec field.
  1232  //
  1233  // Note: all the paths should start with "spec."; the path should correspond to a field defined in the CRD.
  1234  //
  1235  //	Example map: map[string]interface{}{
  1236  //	    "spec.version": "v1.2.3",
  1237  //	}.
  1238  func (c *TestControlPlaneTemplateBuilder) WithSpecFields(fields map[string]interface{}) *TestControlPlaneTemplateBuilder {
  1239  	setSpecFields(c.obj, fields)
  1240  	return c
  1241  }
  1242  
  1243  // WithInfrastructureMachineTemplate adds the given Unstructured object to the ControlPlaneTemplateBuilder as its InfrastructureMachineTemplate.
  1244  func (c *TestControlPlaneTemplateBuilder) WithInfrastructureMachineTemplate(t *unstructured.Unstructured) *TestControlPlaneTemplateBuilder {
  1245  	if err := setNestedRef(c.obj, t, "spec", "template", "spec", "machineTemplate", "infrastructureRef"); err != nil {
  1246  		panic(err)
  1247  	}
  1248  	return c
  1249  }
  1250  
  1251  // Build creates an Unstructured object from the variables passed to the ControlPlaneTemplateBuilder.
  1252  func (c *TestControlPlaneTemplateBuilder) Build() *unstructured.Unstructured {
  1253  	return c.obj
  1254  }
  1255  
  1256  // InfrastructureClusterBuilder holds the variables and objects needed to build a generic InfrastructureCluster.
  1257  type InfrastructureClusterBuilder struct {
  1258  	obj *unstructured.Unstructured
  1259  }
  1260  
  1261  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1262  // to the value of the spec field.
  1263  //
  1264  // Note: all the paths should start with "spec."
  1265  //
  1266  //	Example map: map[string]interface{}{
  1267  //	    "spec.version": "v1.2.3",
  1268  //	}.
  1269  func (i *InfrastructureClusterBuilder) WithSpecFields(fields map[string]interface{}) *InfrastructureClusterBuilder {
  1270  	setSpecFields(i.obj, fields)
  1271  	return i
  1272  }
  1273  
  1274  // InfrastructureCluster returns and InfrastructureClusterBuilder with the given name and namespace.
  1275  func InfrastructureCluster(namespace, name string) *InfrastructureClusterBuilder {
  1276  	obj := &unstructured.Unstructured{}
  1277  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
  1278  	obj.SetKind(GenericInfrastructureClusterKind)
  1279  	obj.SetNamespace(namespace)
  1280  	obj.SetName(name)
  1281  	return &InfrastructureClusterBuilder{obj: obj}
  1282  }
  1283  
  1284  // Build returns an Unstructured object with the information passed to the InfrastructureClusterBuilder.
  1285  func (i *InfrastructureClusterBuilder) Build() *unstructured.Unstructured {
  1286  	return i.obj
  1287  }
  1288  
  1289  // TestInfrastructureClusterBuilder holds the variables and objects needed to build a generic TestInfrastructureCluster.
  1290  type TestInfrastructureClusterBuilder struct {
  1291  	obj *unstructured.Unstructured
  1292  }
  1293  
  1294  // TestInfrastructureCluster returns and TestInfrastructureClusterBuilder with the given name and namespace.
  1295  func TestInfrastructureCluster(namespace, name string) *TestInfrastructureClusterBuilder {
  1296  	obj := &unstructured.Unstructured{}
  1297  	obj.SetAPIVersion(InfrastructureGroupVersion.String())
  1298  	obj.SetKind(TestInfrastructureClusterKind)
  1299  	obj.SetNamespace(namespace)
  1300  	obj.SetName(name)
  1301  	return &TestInfrastructureClusterBuilder{
  1302  		obj: obj,
  1303  	}
  1304  }
  1305  
  1306  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1307  // to the value of the spec field.
  1308  //
  1309  // Note: all the paths should start with "spec."; the path should correspond to a field defined in the CRD.
  1310  //
  1311  //	Example map: map[string]interface{}{
  1312  //	    "spec.version": "v1.2.3",
  1313  //	}.
  1314  func (i *TestInfrastructureClusterBuilder) WithSpecFields(fields map[string]interface{}) *TestInfrastructureClusterBuilder {
  1315  	setSpecFields(i.obj, fields)
  1316  	return i
  1317  }
  1318  
  1319  // Build returns an Unstructured object with the information passed to the InfrastructureClusterBuilder.
  1320  func (i *TestInfrastructureClusterBuilder) Build() *unstructured.Unstructured {
  1321  	return i.obj
  1322  }
  1323  
  1324  // ControlPlaneBuilder holds the variables and objects needed to build a generic object for cluster.spec.controlPlaneRef.
  1325  type ControlPlaneBuilder struct {
  1326  	obj *unstructured.Unstructured
  1327  }
  1328  
  1329  // ControlPlane returns a ControlPlaneBuilder with the given name and Namespace.
  1330  func ControlPlane(namespace, name string) *ControlPlaneBuilder {
  1331  	obj := &unstructured.Unstructured{}
  1332  	obj.SetAPIVersion(ControlPlaneGroupVersion.String())
  1333  	obj.SetKind(GenericControlPlaneKind)
  1334  	obj.SetNamespace(namespace)
  1335  	obj.SetName(name)
  1336  	return &ControlPlaneBuilder{
  1337  		obj: obj,
  1338  	}
  1339  }
  1340  
  1341  // WithInfrastructureMachineTemplate adds the given unstructured object to the ControlPlaneBuilder as its InfrastructureMachineTemplate.
  1342  func (c *ControlPlaneBuilder) WithInfrastructureMachineTemplate(t *unstructured.Unstructured) *ControlPlaneBuilder {
  1343  	// TODO(killianmuldoon): Update to use the internal/contract package, when it is importable from here
  1344  	if err := setNestedRef(c.obj, t, "spec", "machineTemplate", "infrastructureRef"); err != nil {
  1345  		panic(err)
  1346  	}
  1347  	return c
  1348  }
  1349  
  1350  // WithReplicas sets the number of replicas for the ControlPlaneBuilder.
  1351  func (c *ControlPlaneBuilder) WithReplicas(replicas int64) *ControlPlaneBuilder {
  1352  	if err := unstructured.SetNestedField(c.obj.Object, replicas, "spec", "replicas"); err != nil {
  1353  		panic(err)
  1354  	}
  1355  	return c
  1356  }
  1357  
  1358  // WithVersion adds the passed version to the ControlPlaneBuilder.
  1359  func (c *ControlPlaneBuilder) WithVersion(version string) *ControlPlaneBuilder {
  1360  	if err := unstructured.SetNestedField(c.obj.Object, version, "spec", "version"); err != nil {
  1361  		panic(err)
  1362  	}
  1363  	return c
  1364  }
  1365  
  1366  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1367  // to the value of the spec field.
  1368  //
  1369  // Note: all the paths should start with "spec."
  1370  //
  1371  //	Example map: map[string]interface{}{
  1372  //	    "spec.version": "v1.2.3",
  1373  //	}.
  1374  func (c *ControlPlaneBuilder) WithSpecFields(fields map[string]interface{}) *ControlPlaneBuilder {
  1375  	setSpecFields(c.obj, fields)
  1376  	return c
  1377  }
  1378  
  1379  // WithStatusFields sets a map of status fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1380  // to the value of the status field.
  1381  //
  1382  // Note: all the paths should start with "status."
  1383  //
  1384  //	Example map: map[string]interface{}{
  1385  //	    "status.version": "v1.2.3",
  1386  //	}.
  1387  func (c *ControlPlaneBuilder) WithStatusFields(fields map[string]interface{}) *ControlPlaneBuilder {
  1388  	setStatusFields(c.obj, fields)
  1389  	return c
  1390  }
  1391  
  1392  // Build generates an Unstructured object from the information passed to the ControlPlaneBuilder.
  1393  func (c *ControlPlaneBuilder) Build() *unstructured.Unstructured {
  1394  	return c.obj
  1395  }
  1396  
  1397  // TestControlPlaneBuilder holds the variables and objects needed to build a generic object for cluster.spec.controlPlaneRef.
  1398  type TestControlPlaneBuilder struct {
  1399  	obj *unstructured.Unstructured
  1400  }
  1401  
  1402  // TestControlPlane returns a TestControlPlaneBuilder with the given name and Namespace.
  1403  func TestControlPlane(namespace, name string) *ControlPlaneBuilder {
  1404  	obj := &unstructured.Unstructured{}
  1405  	obj.SetAPIVersion(ControlPlaneGroupVersion.String())
  1406  	obj.SetKind(TestControlPlaneKind)
  1407  	obj.SetNamespace(namespace)
  1408  	obj.SetName(name)
  1409  	return &ControlPlaneBuilder{
  1410  		obj: obj,
  1411  	}
  1412  }
  1413  
  1414  // WithInfrastructureMachineTemplate adds the given unstructured object to the TestControlPlaneBuilder as its InfrastructureMachineTemplate.
  1415  func (c *TestControlPlaneBuilder) WithInfrastructureMachineTemplate(t *unstructured.Unstructured) *TestControlPlaneBuilder {
  1416  	// TODO(killianmuldoon): Update to use the internal/contract package, when it is importable from here
  1417  	if err := setNestedRef(c.obj, t, "spec", "machineTemplate", "infrastructureRef"); err != nil {
  1418  		panic(err)
  1419  	}
  1420  	return c
  1421  }
  1422  
  1423  // WithReplicas sets the number of replicas for the TestControlPlaneBuilder.
  1424  func (c *TestControlPlaneBuilder) WithReplicas(replicas int64) *TestControlPlaneBuilder {
  1425  	if err := unstructured.SetNestedField(c.obj.Object, replicas, "spec", "replicas"); err != nil {
  1426  		panic(err)
  1427  	}
  1428  	return c
  1429  }
  1430  
  1431  // WithVersion adds the passed version to the TestControlPlaneBuilder.
  1432  func (c *TestControlPlaneBuilder) WithVersion(version string) *TestControlPlaneBuilder {
  1433  	if err := unstructured.SetNestedField(c.obj.Object, version, "spec", "version"); err != nil {
  1434  		panic(err)
  1435  	}
  1436  	return c
  1437  }
  1438  
  1439  // WithSpecFields sets a map of spec fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1440  // to the value of the spec field.
  1441  //
  1442  // Note: all the paths should start with "spec."
  1443  //
  1444  //	Example map: map[string]interface{}{
  1445  //	    "spec.version": "v1.2.3",
  1446  //	}.
  1447  func (c *TestControlPlaneBuilder) WithSpecFields(fields map[string]interface{}) *TestControlPlaneBuilder {
  1448  	setSpecFields(c.obj, fields)
  1449  	return c
  1450  }
  1451  
  1452  // WithStatusFields sets a map of status fields on the unstructured object. The keys in the map represent the path and the value corresponds
  1453  // to the value of the status field.
  1454  //
  1455  // Note: all the paths should start with "status."
  1456  //
  1457  //	Example map: map[string]interface{}{
  1458  //	    "status.version": "v1.2.3",
  1459  //	}.
  1460  func (c *TestControlPlaneBuilder) WithStatusFields(fields map[string]interface{}) *TestControlPlaneBuilder {
  1461  	setStatusFields(c.obj, fields)
  1462  	return c
  1463  }
  1464  
  1465  // Build generates an Unstructured object from the information passed to the TestControlPlaneBuilder.
  1466  func (c *TestControlPlaneBuilder) Build() *unstructured.Unstructured {
  1467  	return c.obj
  1468  }
  1469  
  1470  // NodeBuilder holds the variables required to build a Node.
  1471  type NodeBuilder struct {
  1472  	name   string
  1473  	status corev1.NodeStatus
  1474  }
  1475  
  1476  // Node returns a NodeBuilder.
  1477  func Node(name string) *NodeBuilder {
  1478  	return &NodeBuilder{
  1479  		name: name,
  1480  	}
  1481  }
  1482  
  1483  // WithStatus adds Status to the NodeBuilder.
  1484  func (n *NodeBuilder) WithStatus(status corev1.NodeStatus) *NodeBuilder {
  1485  	n.status = status
  1486  	return n
  1487  }
  1488  
  1489  // Build produces a new Node from the information passed to the NodeBuilder.
  1490  func (n *NodeBuilder) Build() *corev1.Node {
  1491  	obj := &corev1.Node{
  1492  		ObjectMeta: metav1.ObjectMeta{
  1493  			Name: n.name,
  1494  		},
  1495  		Status: n.status,
  1496  	}
  1497  	return obj
  1498  }
  1499  
  1500  // MachinePoolBuilder holds the variables and objects needed to build a generic MachinePool.
  1501  type MachinePoolBuilder struct {
  1502  	namespace       string
  1503  	name            string
  1504  	bootstrap       *unstructured.Unstructured
  1505  	infrastructure  *unstructured.Unstructured
  1506  	version         *string
  1507  	clusterName     string
  1508  	replicas        *int32
  1509  	labels          map[string]string
  1510  	status          *expv1.MachinePoolStatus
  1511  	minReadySeconds *int32
  1512  }
  1513  
  1514  // MachinePool creates a MachinePoolBuilder with the given name and namespace.
  1515  func MachinePool(namespace, name string) *MachinePoolBuilder {
  1516  	return &MachinePoolBuilder{
  1517  		name:      name,
  1518  		namespace: namespace,
  1519  	}
  1520  }
  1521  
  1522  // WithBootstrap adds the passed Unstructured object to the MachinePoolBuilder as a bootstrap.
  1523  func (m *MachinePoolBuilder) WithBootstrap(ref *unstructured.Unstructured) *MachinePoolBuilder {
  1524  	m.bootstrap = ref
  1525  	return m
  1526  }
  1527  
  1528  // WithInfrastructure adds the passed Unstructured object to the MachinePool builder as an InfrastructureMachinePool.
  1529  func (m *MachinePoolBuilder) WithInfrastructure(ref *unstructured.Unstructured) *MachinePoolBuilder {
  1530  	m.infrastructure = ref
  1531  	return m
  1532  }
  1533  
  1534  // WithLabels adds the given labels to the MachinePoolBuilder.
  1535  func (m *MachinePoolBuilder) WithLabels(labels map[string]string) *MachinePoolBuilder {
  1536  	m.labels = labels
  1537  	return m
  1538  }
  1539  
  1540  // WithVersion sets the passed version on the MachinePool spec.
  1541  func (m *MachinePoolBuilder) WithVersion(version string) *MachinePoolBuilder {
  1542  	m.version = &version
  1543  	return m
  1544  }
  1545  
  1546  // WithClusterName sets the passed clusterName on the MachinePool spec.
  1547  func (m *MachinePoolBuilder) WithClusterName(clusterName string) *MachinePoolBuilder {
  1548  	m.clusterName = clusterName
  1549  	return m
  1550  }
  1551  
  1552  // WithReplicas sets the number of replicas for the MachinePoolBuilder.
  1553  func (m *MachinePoolBuilder) WithReplicas(replicas int32) *MachinePoolBuilder {
  1554  	m.replicas = &replicas
  1555  	return m
  1556  }
  1557  
  1558  // WithStatus sets the passed status object as the status of the MachinePool object.
  1559  func (m *MachinePoolBuilder) WithStatus(status expv1.MachinePoolStatus) *MachinePoolBuilder {
  1560  	m.status = &status
  1561  	return m
  1562  }
  1563  
  1564  // WithMinReadySeconds sets the passed value on the machine pool spec.
  1565  func (m *MachinePoolBuilder) WithMinReadySeconds(minReadySeconds int32) *MachinePoolBuilder {
  1566  	m.minReadySeconds = &minReadySeconds
  1567  	return m
  1568  }
  1569  
  1570  // Build creates a new MachinePool with the variables and objects passed to the MachinePoolBuilder.
  1571  func (m *MachinePoolBuilder) Build() *expv1.MachinePool {
  1572  	obj := &expv1.MachinePool{
  1573  		TypeMeta: metav1.TypeMeta{
  1574  			Kind:       "MachinePool",
  1575  			APIVersion: expv1.GroupVersion.String(),
  1576  		},
  1577  		ObjectMeta: metav1.ObjectMeta{
  1578  			Name:      m.name,
  1579  			Namespace: m.namespace,
  1580  			Labels:    m.labels,
  1581  		},
  1582  		Spec: expv1.MachinePoolSpec{
  1583  			ClusterName:     m.clusterName,
  1584  			Replicas:        m.replicas,
  1585  			MinReadySeconds: m.minReadySeconds,
  1586  			Template: clusterv1.MachineTemplateSpec{
  1587  				Spec: clusterv1.MachineSpec{
  1588  					Version:     m.version,
  1589  					ClusterName: m.clusterName,
  1590  				},
  1591  			},
  1592  		},
  1593  	}
  1594  	if m.bootstrap != nil {
  1595  		obj.Spec.Template.Spec.Bootstrap.ConfigRef = objToRef(m.bootstrap)
  1596  	}
  1597  	if m.infrastructure != nil {
  1598  		obj.Spec.Template.Spec.InfrastructureRef = *objToRef(m.infrastructure)
  1599  	}
  1600  	if m.status != nil {
  1601  		obj.Status = *m.status
  1602  	}
  1603  	return obj
  1604  }
  1605  
  1606  // MachineDeploymentBuilder holds the variables and objects needed to build a generic MachineDeployment.
  1607  type MachineDeploymentBuilder struct {
  1608  	namespace              string
  1609  	name                   string
  1610  	clusterName            string
  1611  	bootstrapTemplate      *unstructured.Unstructured
  1612  	infrastructureTemplate *unstructured.Unstructured
  1613  	selector               *metav1.LabelSelector
  1614  	version                *string
  1615  	replicas               *int32
  1616  	generation             *int64
  1617  	labels                 map[string]string
  1618  	status                 *clusterv1.MachineDeploymentStatus
  1619  	minReadySeconds        *int32
  1620  }
  1621  
  1622  // MachineDeployment creates a MachineDeploymentBuilder with the given name and namespace.
  1623  func MachineDeployment(namespace, name string) *MachineDeploymentBuilder {
  1624  	return &MachineDeploymentBuilder{
  1625  		name:      name,
  1626  		namespace: namespace,
  1627  	}
  1628  }
  1629  
  1630  // WithBootstrapTemplate adds the passed Unstructured object to the MachineDeploymentBuilder as a bootstrapTemplate.
  1631  func (m *MachineDeploymentBuilder) WithBootstrapTemplate(ref *unstructured.Unstructured) *MachineDeploymentBuilder {
  1632  	m.bootstrapTemplate = ref
  1633  	return m
  1634  }
  1635  
  1636  // WithInfrastructureTemplate adds the passed unstructured object to the MachineDeployment builder as an infrastructureMachineTemplate.
  1637  func (m *MachineDeploymentBuilder) WithInfrastructureTemplate(ref *unstructured.Unstructured) *MachineDeploymentBuilder {
  1638  	m.infrastructureTemplate = ref
  1639  	return m
  1640  }
  1641  
  1642  // WithSelector adds the passed selector to the MachineDeployment as the selector.
  1643  func (m *MachineDeploymentBuilder) WithSelector(selector metav1.LabelSelector) *MachineDeploymentBuilder {
  1644  	m.selector = &selector
  1645  	return m
  1646  }
  1647  
  1648  // WithClusterName adds the clusterName to the MachineDeploymentBuilder.
  1649  func (m *MachineDeploymentBuilder) WithClusterName(name string) *MachineDeploymentBuilder {
  1650  	m.clusterName = name
  1651  	return m
  1652  }
  1653  
  1654  // WithLabels adds the given labels to the MachineDeploymentBuilder.
  1655  func (m *MachineDeploymentBuilder) WithLabels(labels map[string]string) *MachineDeploymentBuilder {
  1656  	m.labels = labels
  1657  	return m
  1658  }
  1659  
  1660  // WithVersion sets the passed version on the machine deployment spec.
  1661  func (m *MachineDeploymentBuilder) WithVersion(version string) *MachineDeploymentBuilder {
  1662  	m.version = &version
  1663  	return m
  1664  }
  1665  
  1666  // WithReplicas sets the number of replicas for the MachineDeploymentClassBuilder.
  1667  func (m *MachineDeploymentBuilder) WithReplicas(replicas int32) *MachineDeploymentBuilder {
  1668  	m.replicas = &replicas
  1669  	return m
  1670  }
  1671  
  1672  // WithGeneration sets the passed value on the machine deployments object metadata.
  1673  func (m *MachineDeploymentBuilder) WithGeneration(generation int64) *MachineDeploymentBuilder {
  1674  	m.generation = &generation
  1675  	return m
  1676  }
  1677  
  1678  // WithStatus sets the passed status object as the status of the machine deployment object.
  1679  func (m *MachineDeploymentBuilder) WithStatus(status clusterv1.MachineDeploymentStatus) *MachineDeploymentBuilder {
  1680  	m.status = &status
  1681  	return m
  1682  }
  1683  
  1684  // WithMinReadySeconds sets the passed value on the machine deployment spec.
  1685  func (m *MachineDeploymentBuilder) WithMinReadySeconds(minReadySeconds int32) *MachineDeploymentBuilder {
  1686  	m.minReadySeconds = &minReadySeconds
  1687  	return m
  1688  }
  1689  
  1690  // Build creates a new MachineDeployment with the variables and objects passed to the MachineDeploymentBuilder.
  1691  func (m *MachineDeploymentBuilder) Build() *clusterv1.MachineDeployment {
  1692  	obj := &clusterv1.MachineDeployment{
  1693  		TypeMeta: metav1.TypeMeta{
  1694  			Kind:       "MachineDeployment",
  1695  			APIVersion: clusterv1.GroupVersion.String(),
  1696  		},
  1697  		ObjectMeta: metav1.ObjectMeta{
  1698  			Name:      m.name,
  1699  			Namespace: m.namespace,
  1700  			Labels:    m.labels,
  1701  		},
  1702  	}
  1703  	if m.generation != nil {
  1704  		obj.Generation = *m.generation
  1705  	}
  1706  	if m.version != nil {
  1707  		obj.Spec.Template.Spec.Version = m.version
  1708  	}
  1709  	obj.Spec.Replicas = m.replicas
  1710  	if m.bootstrapTemplate != nil {
  1711  		obj.Spec.Template.Spec.Bootstrap.ConfigRef = objToRef(m.bootstrapTemplate)
  1712  	}
  1713  	if m.infrastructureTemplate != nil {
  1714  		obj.Spec.Template.Spec.InfrastructureRef = *objToRef(m.infrastructureTemplate)
  1715  	}
  1716  	if m.selector != nil {
  1717  		obj.Spec.Selector = *m.selector
  1718  	}
  1719  	if m.status != nil {
  1720  		obj.Status = *m.status
  1721  	}
  1722  	if m.clusterName != "" {
  1723  		obj.Spec.Template.Spec.ClusterName = m.clusterName
  1724  		obj.Spec.ClusterName = m.clusterName
  1725  		if obj.Spec.Selector.MatchLabels == nil {
  1726  			obj.Spec.Selector.MatchLabels = map[string]string{}
  1727  		}
  1728  		obj.Spec.Selector.MatchLabels[clusterv1.ClusterNameLabel] = m.clusterName
  1729  		obj.Spec.Template.Labels = map[string]string{
  1730  			clusterv1.ClusterNameLabel: m.clusterName,
  1731  		}
  1732  	}
  1733  	obj.Spec.MinReadySeconds = m.minReadySeconds
  1734  
  1735  	return obj
  1736  }
  1737  
  1738  // MachineSetBuilder holds the variables and objects needed to build a MachineSet.
  1739  type MachineSetBuilder struct {
  1740  	namespace              string
  1741  	name                   string
  1742  	bootstrapTemplate      *unstructured.Unstructured
  1743  	infrastructureTemplate *unstructured.Unstructured
  1744  	replicas               *int32
  1745  	labels                 map[string]string
  1746  	clusterName            string
  1747  	ownerRefs              []metav1.OwnerReference
  1748  }
  1749  
  1750  // MachineSet creates a MachineSetBuilder with the given name and namespace.
  1751  func MachineSet(namespace, name string) *MachineSetBuilder {
  1752  	return &MachineSetBuilder{
  1753  		name:      name,
  1754  		namespace: namespace,
  1755  	}
  1756  }
  1757  
  1758  // WithBootstrapTemplate adds the passed Unstructured object to the MachineSetBuilder as a bootstrapTemplate.
  1759  func (m *MachineSetBuilder) WithBootstrapTemplate(ref *unstructured.Unstructured) *MachineSetBuilder {
  1760  	m.bootstrapTemplate = ref
  1761  	return m
  1762  }
  1763  
  1764  // WithInfrastructureTemplate adds the passed unstructured object to the MachineSetBuilder as an infrastructureMachineTemplate.
  1765  func (m *MachineSetBuilder) WithInfrastructureTemplate(ref *unstructured.Unstructured) *MachineSetBuilder {
  1766  	m.infrastructureTemplate = ref
  1767  	return m
  1768  }
  1769  
  1770  // WithLabels adds the given labels to the MachineSetBuilder.
  1771  func (m *MachineSetBuilder) WithLabels(labels map[string]string) *MachineSetBuilder {
  1772  	m.labels = labels
  1773  	return m
  1774  }
  1775  
  1776  // WithReplicas sets the number of replicas for the MachineSetBuilder.
  1777  func (m *MachineSetBuilder) WithReplicas(replicas *int32) *MachineSetBuilder {
  1778  	m.replicas = replicas
  1779  	return m
  1780  }
  1781  
  1782  // WithClusterName sets the number of replicas for the MachineSetBuilder.
  1783  func (m *MachineSetBuilder) WithClusterName(name string) *MachineSetBuilder {
  1784  	m.clusterName = name
  1785  	return m
  1786  }
  1787  
  1788  // WithOwnerReferences adds ownerReferences for the MachineSetBuilder.
  1789  func (m *MachineSetBuilder) WithOwnerReferences(ownerRefs []metav1.OwnerReference) *MachineSetBuilder {
  1790  	m.ownerRefs = ownerRefs
  1791  	return m
  1792  }
  1793  
  1794  // Build creates a new MachineSet with the variables and objects passed to the MachineSetBuilder.
  1795  func (m *MachineSetBuilder) Build() *clusterv1.MachineSet {
  1796  	obj := &clusterv1.MachineSet{
  1797  		TypeMeta: metav1.TypeMeta{
  1798  			Kind:       "MachineSet",
  1799  			APIVersion: clusterv1.GroupVersion.String(),
  1800  		},
  1801  		ObjectMeta: metav1.ObjectMeta{
  1802  			Name:            m.name,
  1803  			Namespace:       m.namespace,
  1804  			Labels:          m.labels,
  1805  			OwnerReferences: m.ownerRefs,
  1806  		},
  1807  	}
  1808  	obj.Spec.ClusterName = m.clusterName
  1809  	obj.Spec.Template.Spec.ClusterName = m.clusterName
  1810  	obj.Spec.Replicas = m.replicas
  1811  	if m.bootstrapTemplate != nil {
  1812  		obj.Spec.Template.Spec.Bootstrap.ConfigRef = objToRef(m.bootstrapTemplate)
  1813  	}
  1814  	if m.infrastructureTemplate != nil {
  1815  		obj.Spec.Template.Spec.InfrastructureRef = *objToRef(m.infrastructureTemplate)
  1816  	}
  1817  	return obj
  1818  }
  1819  
  1820  // MachineBuilder holds the variables required to build a Machine.
  1821  type MachineBuilder struct {
  1822  	name        string
  1823  	namespace   string
  1824  	version     *string
  1825  	clusterName string
  1826  	bootstrap   *unstructured.Unstructured
  1827  	labels      map[string]string
  1828  }
  1829  
  1830  // Machine returns a MachineBuilder.
  1831  func Machine(namespace, name string) *MachineBuilder {
  1832  	return &MachineBuilder{
  1833  		name:      name,
  1834  		namespace: namespace,
  1835  	}
  1836  }
  1837  
  1838  // WithVersion adds a version to the MachineBuilder.
  1839  func (m *MachineBuilder) WithVersion(version string) *MachineBuilder {
  1840  	m.version = &version
  1841  	return m
  1842  }
  1843  
  1844  // WithBootstrapTemplate adds a bootstrap template to the MachineBuilder.
  1845  func (m *MachineBuilder) WithBootstrapTemplate(bootstrap *unstructured.Unstructured) *MachineBuilder {
  1846  	m.bootstrap = bootstrap
  1847  	return m
  1848  }
  1849  
  1850  // WithClusterName adds a clusterName to the MachineBuilder.
  1851  func (m *MachineBuilder) WithClusterName(clusterName string) *MachineBuilder {
  1852  	m.clusterName = clusterName
  1853  	return m
  1854  }
  1855  
  1856  // WithLabels adds the given labels to the MachineSetBuilder.
  1857  func (m *MachineBuilder) WithLabels(labels map[string]string) *MachineBuilder {
  1858  	m.labels = labels
  1859  	return m
  1860  }
  1861  
  1862  // Build produces a Machine object from the information passed to the MachineBuilder.
  1863  func (m *MachineBuilder) Build() *clusterv1.Machine {
  1864  	machine := &clusterv1.Machine{
  1865  		TypeMeta: metav1.TypeMeta{
  1866  			Kind:       "Machine",
  1867  			APIVersion: clusterv1.GroupVersion.String(),
  1868  		},
  1869  		ObjectMeta: metav1.ObjectMeta{
  1870  			Namespace: m.namespace,
  1871  			Name:      m.name,
  1872  			Labels:    m.labels,
  1873  		},
  1874  		Spec: clusterv1.MachineSpec{
  1875  			Version:     m.version,
  1876  			ClusterName: m.clusterName,
  1877  		},
  1878  	}
  1879  	if m.bootstrap != nil {
  1880  		machine.Spec.Bootstrap.ConfigRef = objToRef(m.bootstrap)
  1881  	}
  1882  	if m.clusterName != "" {
  1883  		if len(m.labels) == 0 {
  1884  			machine.Labels = map[string]string{}
  1885  		}
  1886  		machine.ObjectMeta.Labels[clusterv1.ClusterNameLabel] = m.clusterName
  1887  	}
  1888  	return machine
  1889  }
  1890  
  1891  // objToRef returns a reference to the given object.
  1892  // Note: This function only operates on Unstructured instead of client.Object
  1893  // because it is only safe to assume for Unstructured that the GVK is set.
  1894  func objToRef(obj *unstructured.Unstructured) *corev1.ObjectReference {
  1895  	gvk := obj.GetObjectKind().GroupVersionKind()
  1896  	return &corev1.ObjectReference{
  1897  		Kind:       gvk.Kind,
  1898  		APIVersion: gvk.GroupVersion().String(),
  1899  		Namespace:  obj.GetNamespace(),
  1900  		Name:       obj.GetName(),
  1901  	}
  1902  }
  1903  
  1904  // setNestedRef sets the value of a nested field to a reference to the refObj provided.
  1905  func setNestedRef(obj, refObj *unstructured.Unstructured, fields ...string) error {
  1906  	ref := map[string]interface{}{
  1907  		"kind":       refObj.GetKind(),
  1908  		"namespace":  refObj.GetNamespace(),
  1909  		"name":       refObj.GetName(),
  1910  		"apiVersion": refObj.GetAPIVersion(),
  1911  	}
  1912  	return unstructured.SetNestedField(obj.UnstructuredContent(), ref, fields...)
  1913  }
  1914  
  1915  // setSpecFields sets fields in an unstructured object from a map.
  1916  func setSpecFields(obj *unstructured.Unstructured, fields map[string]interface{}) {
  1917  	for k, v := range fields {
  1918  		fieldParts := strings.Split(k, ".")
  1919  		if len(fieldParts) == 0 {
  1920  			panic(fmt.Errorf("fieldParts invalid"))
  1921  		}
  1922  		if fieldParts[0] != "spec" {
  1923  			panic(fmt.Errorf("can not set fields outside spec"))
  1924  		}
  1925  		if err := unstructured.SetNestedField(obj.UnstructuredContent(), v, strings.Split(k, ".")...); err != nil {
  1926  			panic(err)
  1927  		}
  1928  	}
  1929  }
  1930  
  1931  // setStatusFields sets fields in an unstructured object from a map.
  1932  func setStatusFields(obj *unstructured.Unstructured, fields map[string]interface{}) {
  1933  	for k, v := range fields {
  1934  		fieldParts := strings.Split(k, ".")
  1935  		if len(fieldParts) == 0 {
  1936  			panic(fmt.Errorf("fieldParts invalid"))
  1937  		}
  1938  		if fieldParts[0] != "status" {
  1939  			panic(fmt.Errorf("can not set fields outside status"))
  1940  		}
  1941  		if err := unstructured.SetNestedField(obj.UnstructuredContent(), v, strings.Split(k, ".")...); err != nil {
  1942  			panic(err)
  1943  		}
  1944  	}
  1945  }
  1946  
  1947  // MachineHealthCheckBuilder holds fields for creating a MachineHealthCheck.
  1948  type MachineHealthCheckBuilder struct {
  1949  	name         string
  1950  	namespace    string
  1951  	ownerRefs    []metav1.OwnerReference
  1952  	selector     metav1.LabelSelector
  1953  	clusterName  string
  1954  	conditions   []clusterv1.UnhealthyCondition
  1955  	maxUnhealthy *intstr.IntOrString
  1956  }
  1957  
  1958  // MachineHealthCheck returns a MachineHealthCheckBuilder with the given name and namespace.
  1959  func MachineHealthCheck(namespace, name string) *MachineHealthCheckBuilder {
  1960  	return &MachineHealthCheckBuilder{
  1961  		name:      name,
  1962  		namespace: namespace,
  1963  	}
  1964  }
  1965  
  1966  // WithSelector adds the selector used to target machines for the MachineHealthCheck.
  1967  func (m *MachineHealthCheckBuilder) WithSelector(selector metav1.LabelSelector) *MachineHealthCheckBuilder {
  1968  	m.selector = selector
  1969  	return m
  1970  }
  1971  
  1972  // WithClusterName adds a cluster name for the MachineHealthCheck.
  1973  func (m *MachineHealthCheckBuilder) WithClusterName(clusterName string) *MachineHealthCheckBuilder {
  1974  	m.clusterName = clusterName
  1975  	return m
  1976  }
  1977  
  1978  // WithUnhealthyConditions adds the spec used to build the parameters of the MachineHealthCheck.
  1979  func (m *MachineHealthCheckBuilder) WithUnhealthyConditions(conditions []clusterv1.UnhealthyCondition) *MachineHealthCheckBuilder {
  1980  	m.conditions = conditions
  1981  	return m
  1982  }
  1983  
  1984  // WithOwnerReferences adds ownerreferences for the MachineHealthCheck.
  1985  func (m *MachineHealthCheckBuilder) WithOwnerReferences(ownerRefs []metav1.OwnerReference) *MachineHealthCheckBuilder {
  1986  	m.ownerRefs = ownerRefs
  1987  	return m
  1988  }
  1989  
  1990  // WithMaxUnhealthy adds a MaxUnhealthyValue for the MachineHealthCheck.
  1991  func (m *MachineHealthCheckBuilder) WithMaxUnhealthy(maxUnhealthy *intstr.IntOrString) *MachineHealthCheckBuilder {
  1992  	m.maxUnhealthy = maxUnhealthy
  1993  	return m
  1994  }
  1995  
  1996  // Build returns a MachineHealthCheck with the supplied details.
  1997  func (m *MachineHealthCheckBuilder) Build() *clusterv1.MachineHealthCheck {
  1998  	// create a MachineHealthCheck with the spec given in the ClusterClass
  1999  	mhc := &clusterv1.MachineHealthCheck{
  2000  		TypeMeta: metav1.TypeMeta{
  2001  			Kind:       "MachineHealthCheck",
  2002  			APIVersion: clusterv1.GroupVersion.String(),
  2003  		},
  2004  		ObjectMeta: metav1.ObjectMeta{
  2005  			Name:            m.name,
  2006  			Namespace:       m.namespace,
  2007  			OwnerReferences: m.ownerRefs,
  2008  		},
  2009  		Spec: clusterv1.MachineHealthCheckSpec{
  2010  			ClusterName:         m.clusterName,
  2011  			Selector:            m.selector,
  2012  			UnhealthyConditions: m.conditions,
  2013  			MaxUnhealthy:        m.maxUnhealthy,
  2014  		},
  2015  	}
  2016  	if m.clusterName != "" {
  2017  		mhc.Labels = map[string]string{clusterv1.ClusterNameLabel: m.clusterName}
  2018  	}
  2019  
  2020  	return mhc
  2021  }