sigs.k8s.io/cluster-api@v1.6.3/api/v1beta1/clusterclass_types.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 v1beta1
    18  
    19  import (
    20  	"reflect"
    21  
    22  	corev1 "k8s.io/api/core/v1"
    23  	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/util/intstr"
    26  )
    27  
    28  // ClusterClassKind represents the Kind of ClusterClass.
    29  const ClusterClassKind = "ClusterClass"
    30  
    31  // +kubebuilder:object:root=true
    32  // +kubebuilder:resource:path=clusterclasses,shortName=cc,scope=Namespaced,categories=cluster-api
    33  // +kubebuilder:storageversion
    34  // +kubebuilder:subresource:status
    35  // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of ClusterClass"
    36  
    37  // ClusterClass is a template which can be used to create managed topologies.
    38  type ClusterClass struct {
    39  	metav1.TypeMeta   `json:",inline"`
    40  	metav1.ObjectMeta `json:"metadata,omitempty"`
    41  
    42  	Spec   ClusterClassSpec   `json:"spec,omitempty"`
    43  	Status ClusterClassStatus `json:"status,omitempty"`
    44  }
    45  
    46  // ClusterClassSpec describes the desired state of the ClusterClass.
    47  type ClusterClassSpec struct {
    48  	// Infrastructure is a reference to a provider-specific template that holds
    49  	// the details for provisioning infrastructure specific cluster
    50  	// for the underlying provider.
    51  	// The underlying provider is responsible for the implementation
    52  	// of the template to an infrastructure cluster.
    53  	// +optional
    54  	Infrastructure LocalObjectTemplate `json:"infrastructure,omitempty"`
    55  
    56  	// ControlPlane is a reference to a local struct that holds the details
    57  	// for provisioning the Control Plane for the Cluster.
    58  	// +optional
    59  	ControlPlane ControlPlaneClass `json:"controlPlane,omitempty"`
    60  
    61  	// Workers describes the worker nodes for the cluster.
    62  	// It is a collection of node types which can be used to create
    63  	// the worker nodes of the cluster.
    64  	// +optional
    65  	Workers WorkersClass `json:"workers,omitempty"`
    66  
    67  	// Variables defines the variables which can be configured
    68  	// in the Cluster topology and are then used in patches.
    69  	// +optional
    70  	Variables []ClusterClassVariable `json:"variables,omitempty"`
    71  
    72  	// Patches defines the patches which are applied to customize
    73  	// referenced templates of a ClusterClass.
    74  	// Note: Patches will be applied in the order of the array.
    75  	// +optional
    76  	Patches []ClusterClassPatch `json:"patches,omitempty"`
    77  }
    78  
    79  // ControlPlaneClass defines the class for the control plane.
    80  type ControlPlaneClass struct {
    81  	// Metadata is the metadata applied to the ControlPlane and the Machines of the ControlPlane
    82  	// if the ControlPlaneTemplate referenced is machine based. If not, it is applied only to the
    83  	// ControlPlane.
    84  	// At runtime this metadata is merged with the corresponding metadata from the topology.
    85  	//
    86  	// This field is supported if and only if the control plane provider template
    87  	// referenced is Machine based.
    88  	// +optional
    89  	Metadata ObjectMeta `json:"metadata,omitempty"`
    90  
    91  	// LocalObjectTemplate contains the reference to the control plane provider.
    92  	LocalObjectTemplate `json:",inline"`
    93  
    94  	// MachineInfrastructure defines the metadata and infrastructure information
    95  	// for control plane machines.
    96  	//
    97  	// This field is supported if and only if the control plane provider template
    98  	// referenced above is Machine based and supports setting replicas.
    99  	//
   100  	// +optional
   101  	MachineInfrastructure *LocalObjectTemplate `json:"machineInfrastructure,omitempty"`
   102  
   103  	// MachineHealthCheck defines a MachineHealthCheck for this ControlPlaneClass.
   104  	// This field is supported if and only if the ControlPlane provider template
   105  	// referenced above is Machine based and supports setting replicas.
   106  	// +optional
   107  	MachineHealthCheck *MachineHealthCheckClass `json:"machineHealthCheck,omitempty"`
   108  
   109  	// NamingStrategy allows changing the naming pattern used when creating the control plane provider object.
   110  	// +optional
   111  	NamingStrategy *ControlPlaneClassNamingStrategy `json:"namingStrategy,omitempty"`
   112  
   113  	// NodeDrainTimeout is the total amount of time that the controller will spend on draining a node.
   114  	// The default value is 0, meaning that the node can be drained without any time limitations.
   115  	// NOTE: NodeDrainTimeout is different from `kubectl drain --timeout`
   116  	// NOTE: This value can be overridden while defining a Cluster.Topology.
   117  	// +optional
   118  	NodeDrainTimeout *metav1.Duration `json:"nodeDrainTimeout,omitempty"`
   119  
   120  	// NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes
   121  	// to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations.
   122  	// NOTE: This value can be overridden while defining a Cluster.Topology.
   123  	// +optional
   124  	NodeVolumeDetachTimeout *metav1.Duration `json:"nodeVolumeDetachTimeout,omitempty"`
   125  
   126  	// NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine
   127  	// hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely.
   128  	// Defaults to 10 seconds.
   129  	// NOTE: This value can be overridden while defining a Cluster.Topology.
   130  	// +optional
   131  	NodeDeletionTimeout *metav1.Duration `json:"nodeDeletionTimeout,omitempty"`
   132  }
   133  
   134  // ControlPlaneClassNamingStrategy defines the naming strategy for control plane objects.
   135  type ControlPlaneClassNamingStrategy struct {
   136  	// Template defines the template to use for generating the name of the ControlPlane object.
   137  	// If not defined, it will fallback to `{{ .cluster.name }}-{{ .random }}`.
   138  	// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
   139  	// get concatenated with a random suffix of length 5.
   140  	// The templating mechanism provides the following arguments:
   141  	// * `.cluster.name`: The name of the cluster object.
   142  	// * `.random`: A random alphanumeric string, without vowels, of length 5.
   143  	// +optional
   144  	Template *string `json:"template,omitempty"`
   145  }
   146  
   147  // WorkersClass is a collection of deployment classes.
   148  type WorkersClass struct {
   149  	// MachineDeployments is a list of machine deployment classes that can be used to create
   150  	// a set of worker nodes.
   151  	// +optional
   152  	MachineDeployments []MachineDeploymentClass `json:"machineDeployments,omitempty"`
   153  
   154  	// MachinePools is a list of machine pool classes that can be used to create
   155  	// a set of worker nodes.
   156  	// +optional
   157  	MachinePools []MachinePoolClass `json:"machinePools,omitempty"`
   158  }
   159  
   160  // MachineDeploymentClass serves as a template to define a set of worker nodes of the cluster
   161  // provisioned using the `ClusterClass`.
   162  type MachineDeploymentClass struct {
   163  	// Class denotes a type of worker node present in the cluster,
   164  	// this name MUST be unique within a ClusterClass and can be referenced
   165  	// in the Cluster to create a managed MachineDeployment.
   166  	Class string `json:"class"`
   167  
   168  	// Template is a local struct containing a collection of templates for creation of
   169  	// MachineDeployment objects representing a set of worker nodes.
   170  	Template MachineDeploymentClassTemplate `json:"template"`
   171  
   172  	// MachineHealthCheck defines a MachineHealthCheck for this MachineDeploymentClass.
   173  	// +optional
   174  	MachineHealthCheck *MachineHealthCheckClass `json:"machineHealthCheck,omitempty"`
   175  
   176  	// FailureDomain is the failure domain the machines will be created in.
   177  	// Must match a key in the FailureDomains map stored on the cluster object.
   178  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass.
   179  	// +optional
   180  	FailureDomain *string `json:"failureDomain,omitempty"`
   181  
   182  	// NamingStrategy allows changing the naming pattern used when creating the MachineDeployment.
   183  	// +optional
   184  	NamingStrategy *MachineDeploymentClassNamingStrategy `json:"namingStrategy,omitempty"`
   185  
   186  	// NodeDrainTimeout is the total amount of time that the controller will spend on draining a node.
   187  	// The default value is 0, meaning that the node can be drained without any time limitations.
   188  	// NOTE: NodeDrainTimeout is different from `kubectl drain --timeout`
   189  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass.
   190  	// +optional
   191  	NodeDrainTimeout *metav1.Duration `json:"nodeDrainTimeout,omitempty"`
   192  
   193  	// NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes
   194  	// to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations.
   195  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass.
   196  	// +optional
   197  	NodeVolumeDetachTimeout *metav1.Duration `json:"nodeVolumeDetachTimeout,omitempty"`
   198  
   199  	// NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine
   200  	// hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely.
   201  	// Defaults to 10 seconds.
   202  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass.
   203  	// +optional
   204  	NodeDeletionTimeout *metav1.Duration `json:"nodeDeletionTimeout,omitempty"`
   205  
   206  	// Minimum number of seconds for which a newly created machine should
   207  	// be ready.
   208  	// Defaults to 0 (machine will be considered available as soon as it
   209  	// is ready)
   210  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass.
   211  	MinReadySeconds *int32 `json:"minReadySeconds,omitempty"`
   212  
   213  	// The deployment strategy to use to replace existing machines with
   214  	// new ones.
   215  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass.
   216  	Strategy *MachineDeploymentStrategy `json:"strategy,omitempty"`
   217  }
   218  
   219  // MachineDeploymentClassTemplate defines how a MachineDeployment generated from a MachineDeploymentClass
   220  // should look like.
   221  type MachineDeploymentClassTemplate struct {
   222  	// Metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment.
   223  	// At runtime this metadata is merged with the corresponding metadata from the topology.
   224  	// +optional
   225  	Metadata ObjectMeta `json:"metadata,omitempty"`
   226  
   227  	// Bootstrap contains the bootstrap template reference to be used
   228  	// for the creation of worker Machines.
   229  	Bootstrap LocalObjectTemplate `json:"bootstrap"`
   230  
   231  	// Infrastructure contains the infrastructure template reference to be used
   232  	// for the creation of worker Machines.
   233  	Infrastructure LocalObjectTemplate `json:"infrastructure"`
   234  }
   235  
   236  // MachineDeploymentClassNamingStrategy defines the naming strategy for machine deployment objects.
   237  type MachineDeploymentClassNamingStrategy struct {
   238  	// Template defines the template to use for generating the name of the MachineDeployment object.
   239  	// If not defined, it will fallback to `{{ .cluster.name }}-{{ .machineDeployment.topologyName }}-{{ .random }}`.
   240  	// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
   241  	// get concatenated with a random suffix of length 5.
   242  	// The templating mechanism provides the following arguments:
   243  	// * `.cluster.name`: The name of the cluster object.
   244  	// * `.random`: A random alphanumeric string, without vowels, of length 5.
   245  	// * `.machineDeployment.topologyName`: The name of the MachineDeployment topology (Cluster.spec.topology.workers.machineDeployments[].name).
   246  	// +optional
   247  	Template *string `json:"template,omitempty"`
   248  }
   249  
   250  // MachineHealthCheckClass defines a MachineHealthCheck for a group of Machines.
   251  type MachineHealthCheckClass struct {
   252  	// UnhealthyConditions contains a list of the conditions that determine
   253  	// whether a node is considered unhealthy. The conditions are combined in a
   254  	// logical OR, i.e. if any of the conditions is met, the node is unhealthy.
   255  	UnhealthyConditions []UnhealthyCondition `json:"unhealthyConditions,omitempty"`
   256  
   257  	// Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by
   258  	// "selector" are not healthy.
   259  	// +optional
   260  	MaxUnhealthy *intstr.IntOrString `json:"maxUnhealthy,omitempty"`
   261  
   262  	// Any further remediation is only allowed if the number of machines selected by "selector" as not healthy
   263  	// is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy.
   264  	// Eg. "[3-5]" - This means that remediation will be allowed only when:
   265  	// (a) there are at least 3 unhealthy machines (and)
   266  	// (b) there are at most 5 unhealthy machines
   267  	// +optional
   268  	// +kubebuilder:validation:Pattern=^\[[0-9]+-[0-9]+\]$
   269  	UnhealthyRange *string `json:"unhealthyRange,omitempty"`
   270  
   271  	// Machines older than this duration without a node will be considered to have
   272  	// failed and will be remediated.
   273  	// If you wish to disable this feature, set the value explicitly to 0.
   274  	// +optional
   275  	NodeStartupTimeout *metav1.Duration `json:"nodeStartupTimeout,omitempty"`
   276  
   277  	// RemediationTemplate is a reference to a remediation template
   278  	// provided by an infrastructure provider.
   279  	//
   280  	// This field is completely optional, when filled, the MachineHealthCheck controller
   281  	// creates a new object from the template referenced and hands off remediation of the machine to
   282  	// a controller that lives outside of Cluster API.
   283  	// +optional
   284  	RemediationTemplate *corev1.ObjectReference `json:"remediationTemplate,omitempty"`
   285  }
   286  
   287  // MachinePoolClass serves as a template to define a pool of worker nodes of the cluster
   288  // provisioned using `ClusterClass`.
   289  type MachinePoolClass struct {
   290  	// Class denotes a type of machine pool present in the cluster,
   291  	// this name MUST be unique within a ClusterClass and can be referenced
   292  	// in the Cluster to create a managed MachinePool.
   293  	Class string `json:"class"`
   294  
   295  	// Template is a local struct containing a collection of templates for creation of
   296  	// MachinePools objects representing a pool of worker nodes.
   297  	Template MachinePoolClassTemplate `json:"template"`
   298  
   299  	// FailureDomains is the list of failure domains the MachinePool should be attached to.
   300  	// Must match a key in the FailureDomains map stored on the cluster object.
   301  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass.
   302  	// +optional
   303  	FailureDomains []string `json:"failureDomains,omitempty"`
   304  
   305  	// NamingStrategy allows changing the naming pattern used when creating the MachinePool.
   306  	// +optional
   307  	NamingStrategy *MachinePoolClassNamingStrategy `json:"namingStrategy,omitempty"`
   308  
   309  	// NodeDrainTimeout is the total amount of time that the controller will spend on draining a node.
   310  	// The default value is 0, meaning that the node can be drained without any time limitations.
   311  	// NOTE: NodeDrainTimeout is different from `kubectl drain --timeout`
   312  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass.
   313  	// +optional
   314  	NodeDrainTimeout *metav1.Duration `json:"nodeDrainTimeout,omitempty"`
   315  
   316  	// NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes
   317  	// to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations.
   318  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass.
   319  	// +optional
   320  	NodeVolumeDetachTimeout *metav1.Duration `json:"nodeVolumeDetachTimeout,omitempty"`
   321  
   322  	// NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine
   323  	// hosts after the Machine Pool is marked for deletion. A duration of 0 will retry deletion indefinitely.
   324  	// Defaults to 10 seconds.
   325  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass.
   326  	// +optional
   327  	NodeDeletionTimeout *metav1.Duration `json:"nodeDeletionTimeout,omitempty"`
   328  
   329  	// Minimum number of seconds for which a newly created machine pool should
   330  	// be ready.
   331  	// Defaults to 0 (machine will be considered available as soon as it
   332  	// is ready)
   333  	// NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass.
   334  	MinReadySeconds *int32 `json:"minReadySeconds,omitempty"`
   335  }
   336  
   337  // MachinePoolClassTemplate defines how a MachinePool generated from a MachinePoolClass
   338  // should look like.
   339  type MachinePoolClassTemplate struct {
   340  	// Metadata is the metadata applied to the MachinePool.
   341  	// At runtime this metadata is merged with the corresponding metadata from the topology.
   342  	// +optional
   343  	Metadata ObjectMeta `json:"metadata,omitempty"`
   344  
   345  	// Bootstrap contains the bootstrap template reference to be used
   346  	// for the creation of the Machines in the MachinePool.
   347  	Bootstrap LocalObjectTemplate `json:"bootstrap"`
   348  
   349  	// Infrastructure contains the infrastructure template reference to be used
   350  	// for the creation of the MachinePool.
   351  	Infrastructure LocalObjectTemplate `json:"infrastructure"`
   352  }
   353  
   354  // MachinePoolClassNamingStrategy defines the naming strategy for machine pool objects.
   355  type MachinePoolClassNamingStrategy struct {
   356  	// Template defines the template to use for generating the name of the MachinePool object.
   357  	// If not defined, it will fallback to `{{ .cluster.name }}-{{ .machinePool.topologyName }}-{{ .random }}`.
   358  	// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
   359  	// get concatenated with a random suffix of length 5.
   360  	// The templating mechanism provides the following arguments:
   361  	// * `.cluster.name`: The name of the cluster object.
   362  	// * `.random`: A random alphanumeric string, without vowels, of length 5.
   363  	// * `.machinePool.topologyName`: The name of the MachinePool topology (Cluster.spec.topology.workers.machinePools[].name).
   364  	// +optional
   365  	Template *string `json:"template,omitempty"`
   366  }
   367  
   368  // IsZero returns true if none of the values of MachineHealthCheckClass are defined.
   369  func (m MachineHealthCheckClass) IsZero() bool {
   370  	return reflect.ValueOf(m).IsZero()
   371  }
   372  
   373  // ClusterClassVariable defines a variable which can
   374  // be configured in the Cluster topology and used in patches.
   375  type ClusterClassVariable struct {
   376  	// Name of the variable.
   377  	Name string `json:"name"`
   378  
   379  	// Required specifies if the variable is required.
   380  	// Note: this applies to the variable as a whole and thus the
   381  	// top-level object defined in the schema. If nested fields are
   382  	// required, this will be specified inside the schema.
   383  	Required bool `json:"required"`
   384  
   385  	// Schema defines the schema of the variable.
   386  	Schema VariableSchema `json:"schema"`
   387  }
   388  
   389  // VariableSchema defines the schema of a variable.
   390  type VariableSchema struct {
   391  	// OpenAPIV3Schema defines the schema of a variable via OpenAPI v3
   392  	// schema. The schema is a subset of the schema used in
   393  	// Kubernetes CRDs.
   394  	OpenAPIV3Schema JSONSchemaProps `json:"openAPIV3Schema"`
   395  }
   396  
   397  // JSONSchemaProps is a JSON-Schema following Specification Draft 4 (http://json-schema.org/).
   398  // This struct has been initially copied from apiextensionsv1.JSONSchemaProps, but all fields
   399  // which are not supported in CAPI have been removed.
   400  type JSONSchemaProps struct {
   401  	// Description is a human-readable description of this variable.
   402  	Description string `json:"description,omitempty"`
   403  
   404  	// Example is an example for this variable.
   405  	Example *apiextensionsv1.JSON `json:"example,omitempty"`
   406  
   407  	// Type is the type of the variable.
   408  	// Valid values are: object, array, string, integer, number or boolean.
   409  	Type string `json:"type"`
   410  
   411  	// Properties specifies fields of an object.
   412  	// NOTE: Can only be set if type is object.
   413  	// NOTE: Properties is mutually exclusive with AdditionalProperties.
   414  	// NOTE: This field uses PreserveUnknownFields and Schemaless,
   415  	// because recursive validation is not possible.
   416  	// +optional
   417  	// +kubebuilder:pruning:PreserveUnknownFields
   418  	// +kubebuilder:validation:Schemaless
   419  	Properties map[string]JSONSchemaProps `json:"properties,omitempty"`
   420  
   421  	// AdditionalProperties specifies the schema of values in a map (keys are always strings).
   422  	// NOTE: Can only be set if type is object.
   423  	// NOTE: AdditionalProperties is mutually exclusive with Properties.
   424  	// NOTE: This field uses PreserveUnknownFields and Schemaless,
   425  	// because recursive validation is not possible.
   426  	// +optional
   427  	// +kubebuilder:pruning:PreserveUnknownFields
   428  	// +kubebuilder:validation:Schemaless
   429  	AdditionalProperties *JSONSchemaProps `json:"additionalProperties,omitempty"`
   430  
   431  	// Required specifies which fields of an object are required.
   432  	// NOTE: Can only be set if type is object.
   433  	// +optional
   434  	Required []string `json:"required,omitempty"`
   435  
   436  	// Items specifies fields of an array.
   437  	// NOTE: Can only be set if type is array.
   438  	// NOTE: This field uses PreserveUnknownFields and Schemaless,
   439  	// because recursive validation is not possible.
   440  	// +optional
   441  	// +kubebuilder:pruning:PreserveUnknownFields
   442  	// +kubebuilder:validation:Schemaless
   443  	Items *JSONSchemaProps `json:"items,omitempty"`
   444  
   445  	// MaxItems is the max length of an array variable.
   446  	// NOTE: Can only be set if type is array.
   447  	// +optional
   448  	MaxItems *int64 `json:"maxItems,omitempty"`
   449  
   450  	// MinItems is the min length of an array variable.
   451  	// NOTE: Can only be set if type is array.
   452  	// +optional
   453  	MinItems *int64 `json:"minItems,omitempty"`
   454  
   455  	// UniqueItems specifies if items in an array must be unique.
   456  	// NOTE: Can only be set if type is array.
   457  	// +optional
   458  	UniqueItems bool `json:"uniqueItems,omitempty"`
   459  
   460  	// Format is an OpenAPI v3 format string. Unknown formats are ignored.
   461  	// For a list of supported formats please see: (of the k8s.io/apiextensions-apiserver version we're currently using)
   462  	// https://github.com/kubernetes/apiextensions-apiserver/blob/master/pkg/apiserver/validation/formats.go
   463  	// NOTE: Can only be set if type is string.
   464  	// +optional
   465  	Format string `json:"format,omitempty"`
   466  
   467  	// MaxLength is the max length of a string variable.
   468  	// NOTE: Can only be set if type is string.
   469  	// +optional
   470  	MaxLength *int64 `json:"maxLength,omitempty"`
   471  
   472  	// MinLength is the min length of a string variable.
   473  	// NOTE: Can only be set if type is string.
   474  	// +optional
   475  	MinLength *int64 `json:"minLength,omitempty"`
   476  
   477  	// Pattern is the regex which a string variable must match.
   478  	// NOTE: Can only be set if type is string.
   479  	// +optional
   480  	Pattern string `json:"pattern,omitempty"`
   481  
   482  	// Maximum is the maximum of an integer or number variable.
   483  	// If ExclusiveMaximum is false, the variable is valid if it is lower than, or equal to, the value of Maximum.
   484  	// If ExclusiveMaximum is true, the variable is valid if it is strictly lower than the value of Maximum.
   485  	// NOTE: Can only be set if type is integer or number.
   486  	// +optional
   487  	Maximum *int64 `json:"maximum,omitempty"`
   488  
   489  	// ExclusiveMaximum specifies if the Maximum is exclusive.
   490  	// NOTE: Can only be set if type is integer or number.
   491  	// +optional
   492  	ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
   493  
   494  	// Minimum is the minimum of an integer or number variable.
   495  	// If ExclusiveMinimum is false, the variable is valid if it is greater than, or equal to, the value of Minimum.
   496  	// If ExclusiveMinimum is true, the variable is valid if it is strictly greater than the value of Minimum.
   497  	// NOTE: Can only be set if type is integer or number.
   498  	// +optional
   499  	Minimum *int64 `json:"minimum,omitempty"`
   500  
   501  	// ExclusiveMinimum specifies if the Minimum is exclusive.
   502  	// NOTE: Can only be set if type is integer or number.
   503  	// +optional
   504  	ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
   505  
   506  	// XPreserveUnknownFields allows setting fields in a variable object
   507  	// which are not defined in the variable schema. This affects fields recursively,
   508  	// except if nested properties or additionalProperties are specified in the schema.
   509  	// +optional
   510  	XPreserveUnknownFields bool `json:"x-kubernetes-preserve-unknown-fields,omitempty"`
   511  
   512  	// Enum is the list of valid values of the variable.
   513  	// NOTE: Can be set for all types.
   514  	// +optional
   515  	Enum []apiextensionsv1.JSON `json:"enum,omitempty"`
   516  
   517  	// Default is the default value of the variable.
   518  	// NOTE: Can be set for all types.
   519  	// +optional
   520  	Default *apiextensionsv1.JSON `json:"default,omitempty"`
   521  }
   522  
   523  // ClusterClassPatch defines a patch which is applied to customize the referenced templates.
   524  type ClusterClassPatch struct {
   525  	// Name of the patch.
   526  	Name string `json:"name"`
   527  
   528  	// Description is a human-readable description of this patch.
   529  	Description string `json:"description,omitempty"`
   530  
   531  	// EnabledIf is a Go template to be used to calculate if a patch should be enabled.
   532  	// It can reference variables defined in .spec.variables and builtin variables.
   533  	// The patch will be enabled if the template evaluates to `true`, otherwise it will
   534  	// be disabled.
   535  	// If EnabledIf is not set, the patch will be enabled per default.
   536  	// +optional
   537  	EnabledIf *string `json:"enabledIf,omitempty"`
   538  
   539  	// Definitions define inline patches.
   540  	// Note: Patches will be applied in the order of the array.
   541  	// Note: Exactly one of Definitions or External must be set.
   542  	// +optional
   543  	Definitions []PatchDefinition `json:"definitions,omitempty"`
   544  
   545  	// External defines an external patch.
   546  	// Note: Exactly one of Definitions or External must be set.
   547  	// +optional
   548  	External *ExternalPatchDefinition `json:"external,omitempty"`
   549  }
   550  
   551  // PatchDefinition defines a patch which is applied to customize the referenced templates.
   552  type PatchDefinition struct {
   553  	// Selector defines on which templates the patch should be applied.
   554  	Selector PatchSelector `json:"selector"`
   555  
   556  	// JSONPatches defines the patches which should be applied on the templates
   557  	// matching the selector.
   558  	// Note: Patches will be applied in the order of the array.
   559  	JSONPatches []JSONPatch `json:"jsonPatches"`
   560  }
   561  
   562  // PatchSelector defines on which templates the patch should be applied.
   563  // Note: Matching on APIVersion and Kind is mandatory, to enforce that the patches are
   564  // written for the correct version. The version of the references in the ClusterClass may
   565  // be automatically updated during reconciliation if there is a newer version for the same contract.
   566  // Note: The results of selection based on the individual fields are ANDed.
   567  type PatchSelector struct {
   568  	// APIVersion filters templates by apiVersion.
   569  	APIVersion string `json:"apiVersion"`
   570  
   571  	// Kind filters templates by kind.
   572  	Kind string `json:"kind"`
   573  
   574  	// MatchResources selects templates based on where they are referenced.
   575  	MatchResources PatchSelectorMatch `json:"matchResources"`
   576  }
   577  
   578  // PatchSelectorMatch selects templates based on where they are referenced.
   579  // Note: The selector must match at least one template.
   580  // Note: The results of selection based on the individual fields are ORed.
   581  type PatchSelectorMatch struct {
   582  	// ControlPlane selects templates referenced in .spec.ControlPlane.
   583  	// Note: this will match the controlPlane and also the controlPlane
   584  	// machineInfrastructure (depending on the kind and apiVersion).
   585  	// +optional
   586  	ControlPlane bool `json:"controlPlane,omitempty"`
   587  
   588  	// InfrastructureCluster selects templates referenced in .spec.infrastructure.
   589  	// +optional
   590  	InfrastructureCluster bool `json:"infrastructureCluster,omitempty"`
   591  
   592  	// MachineDeploymentClass selects templates referenced in specific MachineDeploymentClasses in
   593  	// .spec.workers.machineDeployments.
   594  	// +optional
   595  	MachineDeploymentClass *PatchSelectorMatchMachineDeploymentClass `json:"machineDeploymentClass,omitempty"`
   596  
   597  	// MachinePoolClass selects templates referenced in specific MachinePoolClasses in
   598  	// .spec.workers.machinePools.
   599  	// +optional
   600  	MachinePoolClass *PatchSelectorMatchMachinePoolClass `json:"machinePoolClass,omitempty"`
   601  }
   602  
   603  // PatchSelectorMatchMachineDeploymentClass selects templates referenced
   604  // in specific MachineDeploymentClasses in .spec.workers.machineDeployments.
   605  type PatchSelectorMatchMachineDeploymentClass struct {
   606  	// Names selects templates by class names.
   607  	// +optional
   608  	Names []string `json:"names,omitempty"`
   609  }
   610  
   611  // PatchSelectorMatchMachinePoolClass selects templates referenced
   612  // in specific MachinePoolClasses in .spec.workers.machinePools.
   613  type PatchSelectorMatchMachinePoolClass struct {
   614  	// Names selects templates by class names.
   615  	// +optional
   616  	Names []string `json:"names,omitempty"`
   617  }
   618  
   619  // JSONPatch defines a JSON patch.
   620  type JSONPatch struct {
   621  	// Op defines the operation of the patch.
   622  	// Note: Only `add`, `replace` and `remove` are supported.
   623  	Op string `json:"op"`
   624  
   625  	// Path defines the path of the patch.
   626  	// Note: Only the spec of a template can be patched, thus the path has to start with /spec/.
   627  	// Note: For now the only allowed array modifications are `append` and `prepend`, i.e.:
   628  	// * for op: `add`: only index 0 (prepend) and - (append) are allowed
   629  	// * for op: `replace` or `remove`: no indexes are allowed
   630  	Path string `json:"path"`
   631  
   632  	// Value defines the value of the patch.
   633  	// Note: Either Value or ValueFrom is required for add and replace
   634  	// operations. Only one of them is allowed to be set at the same time.
   635  	// Note: We have to use apiextensionsv1.JSON instead of our JSON type,
   636  	// because controller-tools has a hard-coded schema for apiextensionsv1.JSON
   637  	// which cannot be produced by another type (unset type field).
   638  	// Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111
   639  	// +optional
   640  	Value *apiextensionsv1.JSON `json:"value,omitempty"`
   641  
   642  	// ValueFrom defines the value of the patch.
   643  	// Note: Either Value or ValueFrom is required for add and replace
   644  	// operations. Only one of them is allowed to be set at the same time.
   645  	// +optional
   646  	ValueFrom *JSONPatchValue `json:"valueFrom,omitempty"`
   647  }
   648  
   649  // JSONPatchValue defines the value of a patch.
   650  // Note: Only one of the fields is allowed to be set at the same time.
   651  type JSONPatchValue struct {
   652  	// Variable is the variable to be used as value.
   653  	// Variable can be one of the variables defined in .spec.variables or a builtin variable.
   654  	// +optional
   655  	Variable *string `json:"variable,omitempty"`
   656  
   657  	// Template is the Go template to be used to calculate the value.
   658  	// A template can reference variables defined in .spec.variables and builtin variables.
   659  	// Note: The template must evaluate to a valid YAML or JSON value.
   660  	// +optional
   661  	Template *string `json:"template,omitempty"`
   662  }
   663  
   664  // ExternalPatchDefinition defines an external patch.
   665  // Note: At least one of GenerateExtension or ValidateExtension must be set.
   666  type ExternalPatchDefinition struct {
   667  	// GenerateExtension references an extension which is called to generate patches.
   668  	// +optional
   669  	GenerateExtension *string `json:"generateExtension,omitempty"`
   670  
   671  	// ValidateExtension references an extension which is called to validate the topology.
   672  	// +optional
   673  	ValidateExtension *string `json:"validateExtension,omitempty"`
   674  
   675  	// DiscoverVariablesExtension references an extension which is called to discover variables.
   676  	// +optional
   677  	DiscoverVariablesExtension *string `json:"discoverVariablesExtension,omitempty"`
   678  
   679  	// Settings defines key value pairs to be passed to the extensions.
   680  	// Values defined here take precedence over the values defined in the
   681  	// corresponding ExtensionConfig.
   682  	// +optional
   683  	Settings map[string]string `json:"settings,omitempty"`
   684  }
   685  
   686  // LocalObjectTemplate defines a template for a topology Class.
   687  type LocalObjectTemplate struct {
   688  	// Ref is a required reference to a custom resource
   689  	// offered by a provider.
   690  	Ref *corev1.ObjectReference `json:"ref"`
   691  }
   692  
   693  // ANCHOR: ClusterClassStatus
   694  
   695  // ClusterClassStatus defines the observed state of the ClusterClass.
   696  type ClusterClassStatus struct {
   697  	// Variables is a list of ClusterClassStatusVariable that are defined for the ClusterClass.
   698  	// +optional
   699  	Variables []ClusterClassStatusVariable `json:"variables,omitempty"`
   700  
   701  	// Conditions defines current observed state of the ClusterClass.
   702  	// +optional
   703  	Conditions Conditions `json:"conditions,omitempty"`
   704  
   705  	// ObservedGeneration is the latest generation observed by the controller.
   706  	// +optional
   707  	ObservedGeneration int64 `json:"observedGeneration,omitempty"`
   708  }
   709  
   710  // ClusterClassStatusVariable defines a variable which appears in the status of a ClusterClass.
   711  type ClusterClassStatusVariable struct {
   712  	// Name is the name of the variable.
   713  	Name string `json:"name"`
   714  
   715  	// DefinitionsConflict specifies whether or not there are conflicting definitions for a single variable name.
   716  	// +optional
   717  	DefinitionsConflict bool `json:"definitionsConflict"`
   718  
   719  	// Definitions is a list of definitions for a variable.
   720  	Definitions []ClusterClassStatusVariableDefinition `json:"definitions"`
   721  }
   722  
   723  // ClusterClassStatusVariableDefinition defines a variable which appears in the status of a ClusterClass.
   724  type ClusterClassStatusVariableDefinition struct {
   725  	// From specifies the origin of the variable definition.
   726  	// This will be `inline` for variables defined in the ClusterClass or the name of a patch defined in the ClusterClass
   727  	// for variables discovered from a DiscoverVariables runtime extensions.
   728  	From string `json:"from"`
   729  
   730  	// Required specifies if the variable is required.
   731  	// Note: this applies to the variable as a whole and thus the
   732  	// top-level object defined in the schema. If nested fields are
   733  	// required, this will be specified inside the schema.
   734  	Required bool `json:"required"`
   735  
   736  	// Schema defines the schema of the variable.
   737  	Schema VariableSchema `json:"schema"`
   738  }
   739  
   740  // GetConditions returns the set of conditions for this object.
   741  func (c *ClusterClass) GetConditions() Conditions {
   742  	return c.Status.Conditions
   743  }
   744  
   745  // SetConditions sets the conditions on this object.
   746  func (c *ClusterClass) SetConditions(conditions Conditions) {
   747  	c.Status.Conditions = conditions
   748  }
   749  
   750  // ANCHOR_END: ClusterClassStatus
   751  
   752  // +kubebuilder:object:root=true
   753  
   754  // ClusterClassList contains a list of Cluster.
   755  type ClusterClassList struct {
   756  	metav1.TypeMeta `json:",inline"`
   757  	metav1.ListMeta `json:"metadata,omitempty"`
   758  	Items           []ClusterClass `json:"items"`
   759  }
   760  
   761  func init() {
   762  	objectTypes = append(objectTypes, &ClusterClass{}, &ClusterClassList{})
   763  }