Skip to content

Commit

Permalink
Adding MachineNamingStrategy in KubeadmControlPlane
Browse files Browse the repository at this point in the history
Signed-off-by: Muhammad Adil Ghaffar <[email protected]>
  • Loading branch information
adilGhaffarDev committed Sep 4, 2024
1 parent be86b82 commit 85183ee
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 3 deletions.
19 changes: 19 additions & 0 deletions controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ type KubeadmControlPlaneSpec struct {
// The RemediationStrategy that controls how control plane machine remediation happens.
// +optional
RemediationStrategy *RemediationStrategy `json:"remediationStrategy,omitempty"`

// MachineNamingStrategy allows changing the naming pattern used when creating Machines.
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines.
// +optional
MachineNamingStrategy *MachineNamingStrategy `json:"machineNamingStrategy,omitempty"`
}

// KubeadmControlPlaneMachineTemplate defines the template for Machines
Expand Down Expand Up @@ -228,6 +233,20 @@ type RemediationStrategy struct {
MinHealthyPeriod *metav1.Duration `json:"minHealthyPeriod,omitempty"`
}

// MachineNamingStrategy allows changing the naming pattern used when creating Machines.
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines.
type MachineNamingStrategy struct {
// Template defines the template to use for generating the names of the Machine objects.
// If not defined, it will fallback to `{{ .kubeadmControlPlane.name }}-{{ .random }}`.
// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
// get concatenated with a random suffix of length 5.
// The templating mechanism provides the following arguments:
// * `.kubeadmControlPlane.name`: The name of the KubeadmControlPlane object.
// * `.random`: A random alphanumeric string, without vowels, of length 5.
// +optional
Template *string `json:"template,omitempty"`
}

// KubeadmControlPlaneStatus defines the observed state of KubeadmControlPlane.
type KubeadmControlPlaneStatus struct {
// Selector is the label selector in string format to avoid introspection
Expand Down
25 changes: 25 additions & 0 deletions controlplane/kubeadm/api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion controlplane/kubeadm/internal/controllers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"sigs.k8s.io/cluster-api/controllers/external"
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
"sigs.k8s.io/cluster-api/controlplane/kubeadm/internal"
topologynames "sigs.k8s.io/cluster-api/internal/topology/names"
"sigs.k8s.io/cluster-api/internal/util/ssa"
"sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/cluster-api/util/certs"
Expand Down Expand Up @@ -184,6 +185,7 @@ func (r *KubeadmControlPlaneReconciler) cloneConfigsAndGenerateMachine(ctx conte
if r.DeprecatedInfraMachineNaming {
infraMachineName = names.SimpleNameGenerator.GenerateName(kcp.Spec.MachineTemplate.InfrastructureRef.Name + "-")
}

// Clone the infrastructure template
infraRef, err := external.CreateFromTemplate(ctx, &external.CreateFromTemplateInput{
Client: r.Client,
Expand Down Expand Up @@ -349,7 +351,15 @@ func (r *KubeadmControlPlaneReconciler) computeDesiredMachine(kcp *controlplanev
annotations := map[string]string{}
if existingMachine == nil {
// Creating a new machine
machineName = names.SimpleNameGenerator.GenerateName(kcp.Name + "-")
nameTemplate := "{{ .kubeadmcontrolplane.name }}-{{ .random }}"
if kcp.Spec.MachineNamingStrategy != nil && kcp.Spec.MachineNamingStrategy.Template != nil {
nameTemplate = *kcp.Spec.MachineNamingStrategy.Template
}
generatedMachineName, err := topologynames.KCPMachineNameGenerator(nameTemplate, kcp.Name).GenerateName()
if err != nil {
return nil, errors.Wrap(err, "failed to generate name for KCP machine")
}
machineName = generatedMachineName
version = &kcp.Spec.Version

// Machine's bootstrap config may be missing ClusterConfiguration if it is not the first machine in the control plane.
Expand Down
12 changes: 10 additions & 2 deletions controlplane/kubeadm/internal/controllers/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ func TestCloneConfigsAndGenerateMachine(t *testing.T) {
}
g.Expect(env.CreateAndWait(ctx, genericInfrastructureMachineTemplate)).To(Succeed())

namingTemplateKey := "-testkcp"
kcp := &controlplanev1.KubeadmControlPlane{
ObjectMeta: metav1.ObjectMeta{
Name: "kcp-foo",
Expand All @@ -356,6 +357,9 @@ func TestCloneConfigsAndGenerateMachine(t *testing.T) {
},
},
Version: "v1.16.6",
MachineNamingStrategy: &controlplanev1.MachineNamingStrategy{
Template: ptr.To("{{ .kubeadmcontrolplane.name }}" + namingTemplateKey + "-{{ .random }}"),
},
},
}

Expand All @@ -378,7 +382,7 @@ func TestCloneConfigsAndGenerateMachine(t *testing.T) {
m := machineList.Items[i]
g.Expect(m.Namespace).To(Equal(cluster.Namespace))
g.Expect(m.Name).NotTo(BeEmpty())
g.Expect(m.Name).To(HavePrefix(kcp.Name))
g.Expect(m.Name).To(HavePrefix(kcp.Name + namingTemplateKey))

infraObj, err := external.Get(ctx, r.Client, &m.Spec.InfrastructureRef, m.Spec.InfrastructureRef.Namespace)
g.Expect(err).ToNot(HaveOccurred())
Expand Down Expand Up @@ -487,6 +491,7 @@ func TestKubeadmControlPlaneReconciler_computeDesiredMachine(t *testing.T) {
},
}
kcpMachineTemplateObjectMetaCopy := kcpMachineTemplateObjectMeta.DeepCopy()
namingTemplateKey := "-testkcp"
kcp := &controlplanev1.KubeadmControlPlane{
ObjectMeta: metav1.ObjectMeta{
Name: "testControlPlane",
Expand All @@ -505,6 +510,9 @@ func TestKubeadmControlPlaneReconciler_computeDesiredMachine(t *testing.T) {
ClusterName: "testCluster",
},
},
MachineNamingStrategy: &controlplanev1.MachineNamingStrategy{
Template: ptr.To("{{ .kubeadmcontrolplane.name }}" + namingTemplateKey + "-{{ .random }}"),
},
},
}
clusterConfigurationString := "{\"etcd\":{},\"networking\":{},\"apiServer\":{},\"controllerManager\":{},\"scheduler\":{},\"dns\":{},\"clusterName\":\"testCluster\"}"
Expand Down Expand Up @@ -540,7 +548,7 @@ func TestKubeadmControlPlaneReconciler_computeDesiredMachine(t *testing.T) {
NodeDeletionTimeout: kcp.Spec.MachineTemplate.NodeDeletionTimeout,
NodeVolumeDetachTimeout: kcp.Spec.MachineTemplate.NodeVolumeDetachTimeout,
}
g.Expect(createdMachine.Name).To(HavePrefix(kcp.Name))
g.Expect(createdMachine.Name).To(HavePrefix(kcp.Name + namingTemplateKey))
g.Expect(createdMachine.Namespace).To(Equal(kcp.Namespace))
g.Expect(createdMachine.OwnerReferences).To(HaveLen(1))
g.Expect(createdMachine.OwnerReferences).To(ContainElement(*metav1.NewControllerRef(kcp, controlplanev1.GroupVersion.WithKind("KubeadmControlPlane"))))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ func (webhook *KubeadmControlPlane) ValidateUpdate(_ context.Context, oldObj, ne
{spec, "version"},
{spec, "remediationStrategy"},
{spec, "remediationStrategy", "*"},
{spec, "machineNamingStrategy"},
{spec, "machineNamingStrategy", "*"},
{spec, "rolloutAfter"},
{spec, "rolloutBefore"},
{spec, "rolloutBefore", "*"},
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions internal/topology/names/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ func MachinePoolNameGenerator(templateString, clusterName, topologyName string)
})
}

// KCPMachineNameGenerator returns a generator for creating a kcp machine name.
func KCPMachineNameGenerator(templateString, kubeadmControlPlaneName string) NameGenerator {
return newTemplateGeneratorWithKCP(templateString, kubeadmControlPlaneName,
map[string]interface{}{})
}

// templateGenerator parses the template string as text/template and executes it using
// the passed data to generate a name.
type templateGenerator struct {
Expand All @@ -105,6 +111,18 @@ func newTemplateGenerator(template, clusterName string, data map[string]interfac
}
}

func newTemplateGeneratorWithKCP(template, kubeadmControlPlaneName string, data map[string]interface{}) NameGenerator {
data["kubeadmcontrolplane"] = map[string]interface{}{
"name": kubeadmControlPlaneName,
}
data["random"] = utilrand.String(randomLength)

return &templateGenerator{
template: template,
data: data,
}
}

func (g *templateGenerator) GenerateName() (string, error) {
tpl, err := template.New("template name generator").Option("missingkey=error").Parse(g.template)
if err != nil {
Expand Down

0 comments on commit 85183ee

Please sign in to comment.