Skip to content

Commit 3559d2c

Browse files
Add NamingStrategy to MachineDeployment
Signed-off-by: Muhammad Adil Ghaffar <[email protected]>
1 parent d4a8f10 commit 3559d2c

10 files changed

+364
-50
lines changed

api/v1beta1/machinedeployment_types.go

+22
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ type MachineDeploymentSpec struct {
123123
// +optional
124124
Strategy *MachineDeploymentStrategy `json:"strategy,omitempty"`
125125

126+
// MachineNamingStrategy allows changing the naming pattern used when creating Machines.
127+
// Note: InfraMachines will use the same name as the corresponding Machines.
128+
// +optional
129+
MachineNamingStrategy *MachineNamingStrategy `json:"machineNamingStrategy,omitempty"`
130+
126131
// MinReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available.
127132
// Defaults to 0 (machine will be considered available as soon as the Node is ready)
128133
// +optional
@@ -246,6 +251,23 @@ type RemediationStrategy struct {
246251

247252
// ANCHOR_END: RemediationStrategy
248253

254+
// MachineNamingStrategy allows changing the naming pattern used when creating Machines.
255+
// Note: InfraMachines will use the same name as the corresponding Machines.
256+
type MachineNamingStrategy struct {
257+
// Template defines the template to use for generating the names of the Machine objects.
258+
// If not defined, it will fallback to `{{ .machineDeployment.name }}-{{ .random }}`.
259+
// If the generated name string exceeds 63 characters, it will be trimmed to 58 characters and will
260+
// get concatenated with a random suffix of length 5.
261+
// Length of the template string must not exceed 256 characters.
262+
// The template allows the following variables `.cluster.name`, `.machineDeployment.name` and `.random`.
263+
// The variable `.cluster.name` retrieves the name of the cluster object that owns the Machines being created.
264+
// The variable `.machineDeployment.name` retrieves the name of the MachineDeployment object that owns the Machines being created.
265+
// The variable `.random` is substituted with random alphanumeric string, without vowels, of length 5.
266+
// +optional
267+
// +kubebuilder:validation:MaxLength=256
268+
Template string `json:"template,omitempty"`
269+
}
270+
249271
// ANCHOR: MachineDeploymentStatus
250272

251273
// MachineDeploymentStatus defines the observed state of MachineDeployment.

api/v1beta1/zz_generated.deepcopy.go

+20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta1/zz_generated.openapi.go

+28-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/apis/core/v1alpha3/zz_generated.conversion.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/apis/core/v1alpha4/zz_generated.conversion.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/controllers/machineset/machineset_controller.go

+35-6
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import (
4949
"sigs.k8s.io/cluster-api/controllers/remote"
5050
"sigs.k8s.io/cluster-api/internal/contract"
5151
"sigs.k8s.io/cluster-api/internal/controllers/machine"
52+
topologynames "sigs.k8s.io/cluster-api/internal/topology/names"
5253
"sigs.k8s.io/cluster-api/internal/util/ssa"
5354
"sigs.k8s.io/cluster-api/util"
5455
"sigs.k8s.io/cluster-api/util/annotations"
@@ -399,8 +400,11 @@ func (r *Reconciler) syncMachines(ctx context.Context, machineSet *clusterv1.Mac
399400
}
400401

401402
// Update Machine to propagate in-place mutable fields from the MachineSet.
402-
updatedMachine := r.computeDesiredMachine(machineSet, m)
403-
err := ssa.Patch(ctx, r.Client, machineSetManagerName, updatedMachine, ssa.WithCachingProxy{Cache: r.ssaCache, Original: m})
403+
updatedMachine, err := r.computeDesiredMachine(ctx, machineSet, m)
404+
if err != nil {
405+
return errors.Wrap(err, "failed to update Machine: failed to compute desired Machine")
406+
}
407+
err = ssa.Patch(ctx, r.Client, machineSetManagerName, updatedMachine, ssa.WithCachingProxy{Cache: r.ssaCache, Original: m})
404408
if err != nil {
405409
log.Error(err, "Failed to update Machine", "Machine", klog.KObj(updatedMachine))
406410
return errors.Wrapf(err, "failed to update Machine %q", klog.KObj(updatedMachine))
@@ -486,7 +490,10 @@ func (r *Reconciler) syncReplicas(ctx context.Context, cluster *clusterv1.Cluste
486490
for i := range diff {
487491
// Create a new logger so the global logger is not modified.
488492
log := log
489-
machine := r.computeDesiredMachine(ms, nil)
493+
machine, computeMachineErr := r.computeDesiredMachine(ctx, ms, nil)
494+
if computeMachineErr != nil {
495+
return ctrl.Result{}, errors.Wrap(computeMachineErr, "failed to create Machine: failed to compute desired Machine")
496+
}
490497
// Clone and set the infrastructure and bootstrap references.
491498
var (
492499
infraRef, bootstrapRef *corev1.ObjectReference
@@ -621,14 +628,36 @@ func (r *Reconciler) syncReplicas(ctx context.Context, cluster *clusterv1.Cluste
621628
// There are small differences in how we calculate the Machine depending on if it
622629
// is a create or update. Example: for a new Machine we have to calculate a new name,
623630
// while for an existing Machine we have to use the name of the existing Machine.
624-
func (r *Reconciler) computeDesiredMachine(machineSet *clusterv1.MachineSet, existingMachine *clusterv1.Machine) *clusterv1.Machine {
631+
func (r *Reconciler) computeDesiredMachine(ctx context.Context, machineSet *clusterv1.MachineSet, existingMachine *clusterv1.Machine) (*clusterv1.Machine, error) {
632+
machineName := names.SimpleNameGenerator.GenerateName(fmt.Sprintf("%s-", machineSet.Name))
633+
// If the MachineSet is part of a MachineDeployment, check MachineNamingStrategy
634+
// and name Machine accordingly.
635+
if r.isDeploymentChild(machineSet) {
636+
owner, err := r.getOwnerMachineDeployment(ctx, machineSet)
637+
if err != nil {
638+
return nil, err
639+
}
640+
nameTemplate := "{{ .machineDeployment.name }}-{{ .random }}"
641+
if owner.Spec.MachineNamingStrategy != nil && owner.Spec.MachineNamingStrategy.Template != "" {
642+
nameTemplate = owner.Spec.MachineNamingStrategy.Template
643+
if !strings.Contains(nameTemplate, "{{ .random }}") {
644+
return nil, errors.New("cannot generate MachineDeployment machine name: {{ .random }} is missing in machineNamingStrategy.template")
645+
}
646+
}
647+
generatedMachineName, err := topologynames.MachineDeploymentMachineNameGenerator(nameTemplate, machineSet.Spec.ClusterName, owner.Name).GenerateName()
648+
if err != nil {
649+
return nil, errors.Wrap(err, "failed to generate name for MachineDeployment machine")
650+
}
651+
machineName = generatedMachineName
652+
}
653+
625654
desiredMachine := &clusterv1.Machine{
626655
TypeMeta: metav1.TypeMeta{
627656
APIVersion: clusterv1.GroupVersion.String(),
628657
Kind: "Machine",
629658
},
630659
ObjectMeta: metav1.ObjectMeta{
631-
Name: names.SimpleNameGenerator.GenerateName(fmt.Sprintf("%s-", machineSet.Name)),
660+
Name: machineName,
632661
Namespace: machineSet.Namespace,
633662
// Note: By setting the ownerRef on creation we signal to the Machine controller that this is not a stand-alone Machine.
634663
OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(machineSet, machineSetKind)},
@@ -685,7 +714,7 @@ func (r *Reconciler) computeDesiredMachine(machineSet *clusterv1.MachineSet, exi
685714
desiredMachine.Spec.NodeDeletionTimeout = machineSet.Spec.Template.Spec.NodeDeletionTimeout
686715
desiredMachine.Spec.NodeVolumeDetachTimeout = machineSet.Spec.Template.Spec.NodeVolumeDetachTimeout
687716

688-
return desiredMachine
717+
return desiredMachine, nil
689718
}
690719

691720
// updateExternalObject updates the external object passed in with the

0 commit comments

Comments
 (0)