Skip to content
This repository was archived by the owner on Jul 30, 2021. It is now read-only.

Commit b41e9c2

Browse files
initialize config objects if missing
1 parent e10c244 commit b41e9c2

File tree

2 files changed

+167
-142
lines changed

2 files changed

+167
-142
lines changed

controllers/kubeadmconfig_controller.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ func (r *KubeadmConfigReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result, re
152152
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
153153
}
154154

155-
// if the machine has not ClusterConfiguration and InitConfiguration, requeue
156-
if config.Spec.InitConfiguration == nil && config.Spec.ClusterConfiguration == nil {
155+
// if the machine is configured has a secondary control-plane, requeue
156+
if config.Spec.JoinConfiguration != nil {
157157
log.Info("Control plane is not ready, requeing joining control planes until ready.")
158158
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
159159
}
@@ -250,13 +250,21 @@ func (r *KubeadmConfigReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result, re
250250
}
251251

252252
// Every other case it's a join scenario
253-
// Nb. in this case ClusterConfiguration and JoinConfiguration should not be defined by users, but in case of misconfigurations, CABPK simply ignore them
253+
254+
//In case of join, ClusterConfiguration and InitConfiguration should not be defined by users
255+
if config.Spec.ClusterConfiguration != nil || config.Spec.InitConfiguration != nil {
256+
return ctrl.Result{}, errors.New("Control plane already exists for the cluster, KubeadmConfig objects with ClusterConfiguration or InitConfiguration can not be processed at this stage")
257+
}
254258

255259
// Release any locks that might have been set during init process
256260
initLocker.Release(cluster)
257261

262+
// if the JoinConfiguration is missing, create a default one
258263
if config.Spec.JoinConfiguration == nil {
259-
return ctrl.Result{}, errors.New("Control plane already exists for the cluster, only KubeadmConfig objects with JoinConfiguration are allowed")
264+
config.Spec.JoinConfiguration = &kubeadmv1beta1.JoinConfiguration{}
265+
if util.IsControlPlaneMachine(machine) {
266+
config.Spec.JoinConfiguration.ControlPlane = &kubeadmv1beta1.JoinControlPlane{}
267+
}
260268
}
261269

262270
// ensure that joinConfiguration.Discovery is properly set for joining node on the current cluster

controllers/kubeadmconfig_controller_test.go

Lines changed: 155 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -335,77 +335,93 @@ func TestReconcileKubeadmConfigForInitNodesIfControlPlaneIsNotReady(t *testing.T
335335
cluster.Status.InfrastructureReady = true
336336

337337
controlPlaneMachine := newControlPlaneMachine(cluster, "control-plane-machine")
338-
controlPlaneInitConfig := newControlPlaneInitKubeadmConfig(controlPlaneMachine, "control-plane-init-cfg")
339338

340-
objects := []runtime.Object{
341-
cluster,
342-
controlPlaneMachine,
343-
controlPlaneInitConfig,
339+
var useCases = []struct {
340+
name string
341+
controlPlaneInitConfig *cabpkV1alpha2.KubeadmConfig
342+
}{
343+
{
344+
name: "machine with a fully compiled kubeadm config object",
345+
controlPlaneInitConfig: newControlPlaneInitKubeadmConfig(controlPlaneMachine, "control-plane-init-cfg"),
346+
},
347+
{
348+
name: "machine with an empty kubeadm config object",
349+
controlPlaneInitConfig: newKubeadmConfig(controlPlaneMachine, "control-plane-init-cfg"),
350+
},
344351
}
345-
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
346352

347-
k := &KubeadmConfigReconciler{
348-
Log: log.Log,
349-
Client: myclient,
350-
}
353+
for _, rt := range useCases {
354+
t.Run(rt.name, func(t *testing.T) {
355+
objects := []runtime.Object{
356+
cluster,
357+
controlPlaneMachine,
358+
rt.controlPlaneInitConfig,
359+
}
360+
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
351361

352-
request := ctrl.Request{
353-
NamespacedName: types.NamespacedName{
354-
Namespace: "default",
355-
Name: "control-plane-init-cfg",
356-
},
357-
}
358-
result, err := k.Reconcile(request)
359-
if err != nil {
360-
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
361-
}
362-
if result.Requeue == true {
363-
t.Fatal("did not expected to requeue")
364-
}
365-
if result.RequeueAfter != time.Duration(0) {
366-
t.Fatal("did not expected to requeue after")
367-
}
362+
k := &KubeadmConfigReconciler{
363+
Log: log.Log,
364+
Client: myclient,
365+
}
368366

369-
cfg, err := getKubeadmConfig(myclient, "control-plane-init-cfg")
370-
if err != nil {
371-
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
372-
}
367+
request := ctrl.Request{
368+
NamespacedName: types.NamespacedName{
369+
Namespace: "default",
370+
Name: "control-plane-init-cfg",
371+
},
372+
}
373+
result, err := k.Reconcile(request)
374+
if err != nil {
375+
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
376+
}
377+
if result.Requeue == true {
378+
t.Fatal("did not expected to requeue")
379+
}
380+
if result.RequeueAfter != time.Duration(0) {
381+
t.Fatal("did not expected to requeue after")
382+
}
373383

374-
if cfg.Status.Ready != true {
375-
t.Fatal("Expected status ready")
376-
}
384+
cfg, err := getKubeadmConfig(myclient, "control-plane-init-cfg")
385+
if err != nil {
386+
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
387+
}
377388

378-
if cfg.Status.BootstrapData == nil {
379-
t.Fatal("Expected status ready")
380-
}
389+
if cfg.Status.Ready != true {
390+
t.Fatal("Expected status ready")
391+
}
381392

382-
certsSecret, err := getCertsSecret(myclient, cluster.GetName())
383-
if err != nil {
384-
t.Fatal(fmt.Sprintf("Failed to locate certs secret:\n %+v", err))
385-
}
393+
if cfg.Status.BootstrapData == nil {
394+
t.Fatal("Expected status ready")
395+
}
386396

387-
certsMap := certs.NewCertificatesFromMap(certsSecret.Data)
388-
err = certsMap.Validate()
389-
if err != nil {
390-
t.Fatal(fmt.Sprintf("Certificates not valid:\n %+v", err))
397+
certsSecret, err := getCertsSecret(myclient, cluster.GetName())
398+
if err != nil {
399+
t.Fatal(fmt.Sprintf("Failed to locate certs secret:\n %+v", err))
400+
}
401+
402+
certsMap := certs.NewCertificatesFromMap(certsSecret.Data)
403+
err = certsMap.Validate()
404+
if err != nil {
405+
t.Fatal(fmt.Sprintf("Certificates not valid:\n %+v", err))
406+
}
407+
})
391408
}
392409
}
393410

394411
// Tests for cluster with infrastructure ready, control pane ready
395412

396-
func TestFailIfNotJoinConfigurationAndControlPlaneIsReady(t *testing.T) {
413+
func TestFailIfClusterOrInitConfigurationAndControlPlaneIsReady(t *testing.T) {
397414
cluster := newCluster("cluster")
398415
cluster.Status.InfrastructureReady = true
399416
cluster.Annotations = map[string]string{ControlPlaneReadyAnnotationKey: "true"}
400417

401-
workerMachine := newWorkerMachine(cluster, "worker-machine")
402-
workerJoinConfig := newWorkerJoinKubeadmConfig(workerMachine, "worker-join-cfg")
403-
workerJoinConfig.Spec.JoinConfiguration = nil // Makes workerJoinConfig invalid
418+
controlPaneMachine := newControlPlaneMachine(cluster, "control-plane-machine")
419+
controlPaneJoinConfig := newControlPlaneInitKubeadmConfig(controlPaneMachine, "control-plane-init-cfg")
404420

405421
objects := []runtime.Object{
406422
cluster,
407-
workerMachine,
408-
workerJoinConfig,
423+
controlPaneMachine,
424+
controlPaneJoinConfig,
409425
}
410426
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
411427

@@ -417,7 +433,7 @@ func TestFailIfNotJoinConfigurationAndControlPlaneIsReady(t *testing.T) {
417433
request := ctrl.Request{
418434
NamespacedName: types.NamespacedName{
419435
Namespace: "default",
420-
Name: "worker-join-cfg",
436+
Name: "control-plane-init-cfg",
421437
},
422438
}
423439
_, err := k.Reconcile(request)
@@ -505,106 +521,107 @@ func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) {
505521
cluster.Annotations = map[string]string{ControlPlaneReadyAnnotationKey: "true"}
506522
cluster.Status.APIEndpoints = []capiv1alpha2.APIEndpoint{{Host: "100.105.150.1", Port: 6443}}
507523

508-
workerMachine := newWorkerMachine(cluster, "worker-machine")
509-
workerJoinConfig := newWorkerJoinKubeadmConfig(workerMachine, "worker-join-cfg")
510-
511-
controlPaneMachine := newControlPlaneMachine(cluster, "control-plane-machine")
512-
controlPaneJoinConfig := newControlPlaneJoinKubeadmConfig(controlPaneMachine, "control-plane-join-cfg")
513-
514-
objects := []runtime.Object{
515-
cluster,
516-
workerMachine,
517-
workerJoinConfig,
518-
controlPaneMachine,
519-
controlPaneJoinConfig,
520-
}
521-
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
522-
523-
// stage a secret for certs
524-
certificates, _ := certs.NewCertificates()
525-
secret := &corev1.Secret{
526-
ObjectMeta: metav1.ObjectMeta{
527-
Name: ClusterCertificatesSecretName(cluster.GetName()),
528-
Namespace: controlPaneJoinConfig.GetNamespace(),
524+
var useCases = []struct {
525+
name string
526+
machine *capiv1alpha2.Machine
527+
configName string
528+
configBuilder func(machine *capiv1alpha2.Machine, name string) *cabpkV1alpha2.KubeadmConfig
529+
}{
530+
{
531+
name: "Join a worker node with a fully compiled kubeadm config object",
532+
machine: newWorkerMachine(cluster, "worker-machine"),
533+
configName: "worker-join-cfg",
534+
configBuilder: newWorkerJoinKubeadmConfig,
535+
},
536+
{
537+
name: "Join a worker node with an empty kubeadm config object",
538+
machine: newWorkerMachine(cluster, "worker-machine"),
539+
configName: "worker-join-cfg",
540+
configBuilder: newKubeadmConfig,
541+
},
542+
{
543+
name: "Join a control plane node with a fully compiled kubeadm config object",
544+
machine: newControlPlaneMachine(cluster, "control-plane-machine"),
545+
configName: "control-plane-join-cfg",
546+
configBuilder: newControlPlaneJoinKubeadmConfig,
547+
},
548+
{
549+
name: "Join a control plane node with an empty kubeadm config object",
550+
machine: newControlPlaneMachine(cluster, "control-plane-machine"),
551+
configName: "control-plane-join-cfg",
552+
configBuilder: newKubeadmConfig,
529553
},
530-
Data: certificates.ToMap(),
531554
}
532-
_ = myclient.Create(context.Background(), secret)
533555

534-
k := &KubeadmConfigReconciler{
535-
Log: log.Log,
536-
Client: myclient,
537-
SecretsClientFactory: newFakeSecretFactory(),
538-
}
556+
for _, rt := range useCases {
557+
t.Run(rt.name, func(t *testing.T) {
539558

540-
request := ctrl.Request{
541-
NamespacedName: types.NamespacedName{
542-
Namespace: "default",
543-
Name: "worker-join-cfg",
544-
},
545-
}
546-
result, err := k.Reconcile(request)
547-
if err != nil {
548-
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
549-
}
550-
if result.Requeue == true {
551-
t.Fatal("did not expected to requeue")
552-
}
553-
if result.RequeueAfter != time.Duration(0) {
554-
t.Fatal("did not expected to requeue after")
555-
}
559+
config := rt.configBuilder(rt.machine, rt.configName)
556560

557-
cfg, err := getKubeadmConfig(myclient, "worker-join-cfg")
558-
if err != nil {
559-
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
560-
}
561+
objects := []runtime.Object{
562+
cluster,
563+
rt.machine,
564+
config,
565+
}
566+
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
561567

562-
if cfg.Status.Ready != true {
563-
t.Fatal("Expected status ready")
564-
}
568+
// stage a secret for certs
569+
certificates, _ := certs.NewCertificates()
570+
secret := &corev1.Secret{
571+
ObjectMeta: metav1.ObjectMeta{
572+
Name: ClusterCertificatesSecretName(cluster.GetName()),
573+
Namespace: config.GetNamespace(),
574+
},
575+
Data: certificates.ToMap(),
576+
}
577+
_ = myclient.Create(context.Background(), secret)
565578

566-
if cfg.Status.BootstrapData == nil {
567-
t.Fatal("Expected status ready")
568-
}
579+
k := &KubeadmConfigReconciler{
580+
Log: log.Log,
581+
Client: myclient,
582+
SecretsClientFactory: newFakeSecretFactory(),
583+
}
569584

570-
request = ctrl.Request{
571-
NamespacedName: types.NamespacedName{
572-
Namespace: "default",
573-
Name: "control-plane-join-cfg",
574-
},
575-
}
576-
result, err = k.Reconcile(request)
577-
if err != nil {
578-
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
579-
}
580-
if result.Requeue == true {
581-
t.Fatal("did not expected to requeue")
582-
}
583-
if result.RequeueAfter != time.Duration(0) {
584-
t.Fatal("did not expected to requeue after")
585-
}
585+
request := ctrl.Request{
586+
NamespacedName: types.NamespacedName{
587+
Namespace: config.GetNamespace(),
588+
Name: rt.configName,
589+
},
590+
}
591+
result, err := k.Reconcile(request)
592+
if err != nil {
593+
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
594+
}
595+
if result.Requeue == true {
596+
t.Fatal("did not expected to requeue")
597+
}
598+
if result.RequeueAfter != time.Duration(0) {
599+
t.Fatal("did not expected to requeue after")
600+
}
586601

587-
cfg, err = getKubeadmConfig(myclient, "control-plane-join-cfg")
588-
if err != nil {
589-
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
590-
}
602+
cfg, err := getKubeadmConfig(myclient, rt.configName)
603+
if err != nil {
604+
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
605+
}
591606

592-
if cfg.Status.Ready != true {
593-
t.Fatal("Expected status ready")
594-
}
607+
if cfg.Status.Ready != true {
608+
t.Fatal("Expected status ready")
609+
}
595610

596-
if cfg.Status.BootstrapData == nil {
597-
t.Fatal("Expected status ready")
598-
}
611+
if cfg.Status.BootstrapData == nil {
612+
t.Fatal("Expected status ready")
613+
}
599614

600-
myremoteclient, _ := k.SecretsClientFactory.NewSecretsClient(nil, nil)
601-
l, err := myremoteclient.List(metav1.ListOptions{})
602-
if err != nil {
603-
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
604-
}
615+
myremoteclient, _ := k.SecretsClientFactory.NewSecretsClient(nil, nil)
616+
l, err := myremoteclient.List(metav1.ListOptions{})
617+
if err != nil {
618+
t.Fatal(fmt.Sprintf("Failed to get secrets after reconcyle:\n %+v", err))
619+
}
605620

606-
if len(l.Items) != 2 {
607-
t.Fatal(fmt.Sprintf("Failed to reconcile:\n %+v", err))
621+
if len(l.Items) != 1 {
622+
t.Fatal(fmt.Sprintf("Failed to bootstrap token secrets:\n %+v", err))
623+
}
624+
})
608625
}
609626
}
610627

0 commit comments

Comments
 (0)