sigs.k8s.io/cluster-api@v1.6.3/api/v1beta1/machineset_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  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    21  	metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
    22  	"k8s.io/apimachinery/pkg/labels"
    23  	"k8s.io/apimachinery/pkg/util/validation/field"
    24  
    25  	capierrors "sigs.k8s.io/cluster-api/errors"
    26  )
    27  
    28  const (
    29  	// MachineSetTopologyFinalizer is the finalizer used by the topology MachineDeployment controller to
    30  	// clean up referenced template resources if necessary when a MachineSet is being deleted.
    31  	MachineSetTopologyFinalizer = "machineset.topology.cluster.x-k8s.io"
    32  )
    33  
    34  // ANCHOR: MachineSetSpec
    35  
    36  // MachineSetSpec defines the desired state of MachineSet.
    37  type MachineSetSpec struct {
    38  	// ClusterName is the name of the Cluster this object belongs to.
    39  	// +kubebuilder:validation:MinLength=1
    40  	ClusterName string `json:"clusterName"`
    41  
    42  	// Replicas is the number of desired replicas.
    43  	// This is a pointer to distinguish between explicit zero and unspecified.
    44  	// Defaults to 1.
    45  	// +optional
    46  	// +kubebuilder:default=1
    47  	Replicas *int32 `json:"replicas,omitempty"`
    48  
    49  	// MinReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available.
    50  	// Defaults to 0 (machine will be considered available as soon as the Node is ready)
    51  	// +optional
    52  	MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
    53  
    54  	// DeletePolicy defines the policy used to identify nodes to delete when downscaling.
    55  	// Defaults to "Random".  Valid values are "Random, "Newest", "Oldest"
    56  	// +kubebuilder:validation:Enum=Random;Newest;Oldest
    57  	// +optional
    58  	DeletePolicy string `json:"deletePolicy,omitempty"`
    59  
    60  	// Selector is a label query over machines that should match the replica count.
    61  	// Label keys and values that must match in order to be controlled by this MachineSet.
    62  	// It must match the machine template's labels.
    63  	// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
    64  	Selector metav1.LabelSelector `json:"selector"`
    65  
    66  	// Template is the object that describes the machine that will be created if
    67  	// insufficient replicas are detected.
    68  	// Object references to custom resources are treated as templates.
    69  	// +optional
    70  	Template MachineTemplateSpec `json:"template,omitempty"`
    71  }
    72  
    73  // ANCHOR_END: MachineSetSpec
    74  
    75  // ANCHOR: MachineTemplateSpec
    76  
    77  // MachineTemplateSpec describes the data needed to create a Machine from a template.
    78  type MachineTemplateSpec struct {
    79  	// Standard object's metadata.
    80  	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
    81  	// +optional
    82  	ObjectMeta `json:"metadata,omitempty"`
    83  
    84  	// Specification of the desired behavior of the machine.
    85  	// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
    86  	// +optional
    87  	Spec MachineSpec `json:"spec,omitempty"`
    88  }
    89  
    90  // ANCHOR_END: MachineTemplateSpec
    91  
    92  // MachineSetDeletePolicy defines how priority is assigned to nodes to delete when
    93  // downscaling a MachineSet. Defaults to "Random".
    94  type MachineSetDeletePolicy string
    95  
    96  const (
    97  	// RandomMachineSetDeletePolicy prioritizes both Machines that have the annotation
    98  	// "cluster.x-k8s.io/delete-machine=yes" and Machines that are unhealthy
    99  	// (Status.FailureReason or Status.FailureMessage are set to a non-empty value
   100  	// or NodeHealthy type of Status.Conditions is not true).
   101  	// Finally, it picks Machines at random to delete.
   102  	RandomMachineSetDeletePolicy MachineSetDeletePolicy = "Random"
   103  
   104  	// NewestMachineSetDeletePolicy prioritizes both Machines that have the annotation
   105  	// "cluster.x-k8s.io/delete-machine=yes" and Machines that are unhealthy
   106  	// (Status.FailureReason or Status.FailureMessage are set to a non-empty value
   107  	// or NodeHealthy type of Status.Conditions is not true).
   108  	// It then prioritizes the newest Machines for deletion based on the Machine's CreationTimestamp.
   109  	NewestMachineSetDeletePolicy MachineSetDeletePolicy = "Newest"
   110  
   111  	// OldestMachineSetDeletePolicy prioritizes both Machines that have the annotation
   112  	// "cluster.x-k8s.io/delete-machine=yes" and Machines that are unhealthy
   113  	// (Status.FailureReason or Status.FailureMessage are set to a non-empty value
   114  	// or NodeHealthy type of Status.Conditions is not true).
   115  	// It then prioritizes the oldest Machines for deletion based on the Machine's CreationTimestamp.
   116  	OldestMachineSetDeletePolicy MachineSetDeletePolicy = "Oldest"
   117  )
   118  
   119  // ANCHOR: MachineSetStatus
   120  
   121  // MachineSetStatus defines the observed state of MachineSet.
   122  type MachineSetStatus struct {
   123  	// Selector is the same as the label selector but in the string format to avoid introspection
   124  	// by clients. The string will be in the same format as the query-param syntax.
   125  	// More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors
   126  	// +optional
   127  	Selector string `json:"selector,omitempty"`
   128  
   129  	// Replicas is the most recently observed number of replicas.
   130  	// +optional
   131  	Replicas int32 `json:"replicas"`
   132  
   133  	// The number of replicas that have labels matching the labels of the machine template of the MachineSet.
   134  	// +optional
   135  	FullyLabeledReplicas int32 `json:"fullyLabeledReplicas"`
   136  
   137  	// The number of ready replicas for this MachineSet. A machine is considered ready when the node has been created and is "Ready".
   138  	// +optional
   139  	ReadyReplicas int32 `json:"readyReplicas"`
   140  
   141  	// The number of available replicas (ready for at least minReadySeconds) for this MachineSet.
   142  	// +optional
   143  	AvailableReplicas int32 `json:"availableReplicas"`
   144  
   145  	// ObservedGeneration reflects the generation of the most recently observed MachineSet.
   146  	// +optional
   147  	ObservedGeneration int64 `json:"observedGeneration,omitempty"`
   148  
   149  	// In the event that there is a terminal problem reconciling the
   150  	// replicas, both FailureReason and FailureMessage will be set. FailureReason
   151  	// will be populated with a succinct value suitable for machine
   152  	// interpretation, while FailureMessage will contain a more verbose
   153  	// string suitable for logging and human consumption.
   154  	//
   155  	// These fields should not be set for transitive errors that a
   156  	// controller faces that are expected to be fixed automatically over
   157  	// time (like service outages), but instead indicate that something is
   158  	// fundamentally wrong with the MachineTemplate's spec or the configuration of
   159  	// the machine controller, and that manual intervention is required. Examples
   160  	// of terminal errors would be invalid combinations of settings in the
   161  	// spec, values that are unsupported by the machine controller, or the
   162  	// responsible machine controller itself being critically misconfigured.
   163  	//
   164  	// Any transient errors that occur during the reconciliation of Machines
   165  	// can be added as events to the MachineSet object and/or logged in the
   166  	// controller's output.
   167  	// +optional
   168  	FailureReason *capierrors.MachineSetStatusError `json:"failureReason,omitempty"`
   169  	// +optional
   170  	FailureMessage *string `json:"failureMessage,omitempty"`
   171  	// Conditions defines current service state of the MachineSet.
   172  	// +optional
   173  	Conditions Conditions `json:"conditions,omitempty"`
   174  }
   175  
   176  // ANCHOR_END: MachineSetStatus
   177  
   178  // Validate validates the MachineSet fields.
   179  func (m *MachineSet) Validate() field.ErrorList {
   180  	errors := field.ErrorList{}
   181  
   182  	// validate spec.selector and spec.template.labels
   183  	fldPath := field.NewPath("spec")
   184  	errors = append(errors, metav1validation.ValidateLabelSelector(&m.Spec.Selector, metav1validation.LabelSelectorValidationOptions{}, fldPath.Child("selector"))...)
   185  	if len(m.Spec.Selector.MatchLabels)+len(m.Spec.Selector.MatchExpressions) == 0 {
   186  		errors = append(errors, field.Invalid(fldPath.Child("selector"), m.Spec.Selector, "empty selector is not valid for MachineSet."))
   187  	}
   188  	selector, err := metav1.LabelSelectorAsSelector(&m.Spec.Selector)
   189  	if err != nil {
   190  		errors = append(errors, field.Invalid(fldPath.Child("selector"), m.Spec.Selector, "invalid label selector."))
   191  	} else {
   192  		labels := labels.Set(m.Spec.Template.Labels)
   193  		if !selector.Matches(labels) {
   194  			errors = append(errors, field.Invalid(fldPath.Child("template", "metadata", "labels"), m.Spec.Template.Labels, "`selector` does not match template `labels`"))
   195  		}
   196  	}
   197  
   198  	return errors
   199  }
   200  
   201  // +kubebuilder:object:root=true
   202  // +kubebuilder:resource:path=machinesets,shortName=ms,scope=Namespaced,categories=cluster-api
   203  // +kubebuilder:storageversion
   204  // +kubebuilder:subresource:status
   205  // +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector
   206  // +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".spec.clusterName",description="Cluster"
   207  // +kubebuilder:printcolumn:name="Desired",type=integer,JSONPath=".spec.replicas",description="Total number of machines desired by this machineset",priority=10
   208  // +kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".status.replicas",description="Total number of non-terminated machines targeted by this machineset"
   209  // +kubebuilder:printcolumn:name="Ready",type="integer",JSONPath=".status.readyReplicas",description="Total number of ready machines targeted by this machineset."
   210  // +kubebuilder:printcolumn:name="Available",type="integer",JSONPath=".status.availableReplicas",description="Total number of available machines (ready for at least minReadySeconds)"
   211  // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of MachineSet"
   212  // +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.template.spec.version",description="Kubernetes version associated with this MachineSet"
   213  
   214  // MachineSet is the Schema for the machinesets API.
   215  type MachineSet struct {
   216  	metav1.TypeMeta   `json:",inline"`
   217  	metav1.ObjectMeta `json:"metadata,omitempty"`
   218  
   219  	Spec   MachineSetSpec   `json:"spec,omitempty"`
   220  	Status MachineSetStatus `json:"status,omitempty"`
   221  }
   222  
   223  // GetConditions returns the set of conditions for the MachineSet.
   224  func (m *MachineSet) GetConditions() Conditions {
   225  	return m.Status.Conditions
   226  }
   227  
   228  // SetConditions updates the set of conditions on the MachineSet.
   229  func (m *MachineSet) SetConditions(conditions Conditions) {
   230  	m.Status.Conditions = conditions
   231  }
   232  
   233  // +kubebuilder:object:root=true
   234  
   235  // MachineSetList contains a list of MachineSet.
   236  type MachineSetList struct {
   237  	metav1.TypeMeta `json:",inline"`
   238  	metav1.ListMeta `json:"metadata,omitempty"`
   239  	Items           []MachineSet `json:"items"`
   240  }
   241  
   242  func init() {
   243  	objectTypes = append(objectTypes, &MachineSet{}, &MachineSetList{})
   244  }