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

Commit 070caae

Browse files
committed
Add test and improved logging
1 parent a43cb19 commit 070caae

File tree

3 files changed

+110
-3
lines changed

3 files changed

+110
-3
lines changed

controllers/kubeadmconfig_controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,13 @@ func (r *KubeadmConfigReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result, re
150150
return ctrl.Result{}, err
151151
}
152152

153+
log.Info("refreshing token until the infrastructure has a chance to consume it")
153154
err = refreshToken(secretsClient, token)
154155
if err != nil {
155156
// It would be nice to re-create the bootstrap token if the error was "not found", but we have no way to update the Machine's bootstrap data
156157
return ctrl.Result{}, errors.Wrapf(err, "failed to refresh bootstrap token")
157158
}
159+
return ctrl.Result{}, nil
158160
}
159161

160162
// Wait patiently for the infrastructure to be ready

controllers/kubeadmconfig_controller_test.go

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package controllers
1818

1919
import (
20+
"bytes"
2021
"context"
2122
"fmt"
2223
"reflect"
@@ -30,6 +31,7 @@ import (
3031
"k8s.io/apimachinery/pkg/types"
3132
fakeclient "k8s.io/client-go/kubernetes/fake"
3233
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
34+
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
3335
"k8s.io/klog/klogr"
3436
bootstrapv1 "sigs.k8s.io/cluster-api-bootstrap-provider-kubeadm/api/v1alpha2"
3537
internalcluster "sigs.k8s.io/cluster-api-bootstrap-provider-kubeadm/internal/cluster"
@@ -613,11 +615,114 @@ func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) {
613615
myremoteclient, _ := k.SecretsClientFactory.NewSecretsClient(nil, nil)
614616
l, err := myremoteclient.List(metav1.ListOptions{})
615617
if err != nil {
616-
t.Fatalf("Failed to reconcile:\n %+v", err)
618+
t.Fatalf("Failed to read secrets:\n %+v", err)
617619
}
618620

619621
if len(l.Items) != 2 {
620-
t.Fatalf("Failed to reconcile:\n %+v", err)
622+
t.Fatalf("Expected two bootstrap tokens, saw:\n %+d", len(l.Items))
623+
}
624+
625+
// ensure that the token is refreshed...
626+
tokenExpires := make([][]byte, len(l.Items))
627+
628+
for i, item := range l.Items {
629+
tokenExpires[i] = item.Data[bootstrapapi.BootstrapTokenExpirationKey]
630+
}
631+
632+
<-time.After(1 * time.Second)
633+
634+
for _, req := range []ctrl.Request{
635+
{
636+
NamespacedName: types.NamespacedName{
637+
Namespace: "default",
638+
Name: "worker-join-cfg",
639+
},
640+
},
641+
{
642+
NamespacedName: types.NamespacedName{
643+
Namespace: "default",
644+
Name: "control-plane-join-cfg",
645+
},
646+
},
647+
} {
648+
649+
result, err := k.Reconcile(req)
650+
if err != nil {
651+
t.Fatalf("Failed to reconcile:\n %+v", err)
652+
}
653+
if result.Requeue == true {
654+
t.Fatal("did not expect to requeue")
655+
}
656+
if result.RequeueAfter != time.Duration(0) {
657+
t.Fatal("did not expect to requeue after")
658+
}
659+
}
660+
661+
l, err = myremoteclient.List(metav1.ListOptions{})
662+
if err != nil {
663+
t.Fatalf("Failed to read secrets:\n %+v", err)
664+
}
665+
666+
if len(l.Items) != 2 {
667+
t.Fatalf("Expected two bootstrap tokens, saw:\n %+d", len(l.Items))
668+
}
669+
670+
for i, item := range l.Items {
671+
if bytes.Equal(tokenExpires[i], item.Data[bootstrapapi.BootstrapTokenExpirationKey]) {
672+
t.Fatal("Reconcile should have refreshed bootstrap token's expiration until the infrastructure was ready")
673+
}
674+
tokenExpires[i] = item.Data[bootstrapapi.BootstrapTokenExpirationKey]
675+
}
676+
677+
// ...until the infrastructure is marked "ready"
678+
workerMachine.Status.InfrastructureReady = true
679+
myclient.Update(context.Background(), workerMachine)
680+
681+
controlPlaneJoinMachine.Status.InfrastructureReady = true
682+
myclient.Update(context.Background(), controlPlaneJoinMachine)
683+
684+
<-time.After(1 * time.Second)
685+
686+
for _, req := range []ctrl.Request{
687+
{
688+
NamespacedName: types.NamespacedName{
689+
Namespace: "default",
690+
Name: "worker-join-cfg",
691+
},
692+
},
693+
{
694+
NamespacedName: types.NamespacedName{
695+
Namespace: "default",
696+
Name: "control-plane-join-cfg",
697+
},
698+
},
699+
} {
700+
701+
result, err := k.Reconcile(req)
702+
if err != nil {
703+
t.Fatalf("Failed to reconcile:\n %+v", err)
704+
}
705+
if result.Requeue == true {
706+
t.Fatal("did not expect to requeue")
707+
}
708+
if result.RequeueAfter != time.Duration(0) {
709+
t.Fatal("did not expect to requeue after")
710+
}
711+
}
712+
713+
l, err = myremoteclient.List(metav1.ListOptions{})
714+
if err != nil {
715+
t.Fatalf("Failed to read secrets:\n %+v", err)
716+
}
717+
718+
if len(l.Items) != 2 {
719+
t.Fatalf("Expected two bootstrap tokens, saw:\n %+d", len(l.Items))
720+
}
721+
722+
for i, item := range l.Items {
723+
if !bytes.Equal(tokenExpires[i], item.Data[bootstrapapi.BootstrapTokenExpirationKey]) {
724+
t.Fatal("Reconcile should have let the bootstrap token expire after the infrastructure was ready")
725+
}
621726
}
622727
}
623728

controllers/token.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import (
3232

3333
var (
3434
// DefaultTokenTTL is the amount of time a bootstrap token (and therefore a KubeadmConfig) will be valid
35-
DefaultTokenTTL = 10 * time.Minute
35+
DefaultTokenTTL = 15 * time.Minute
3636
)
3737

3838
// ClusterSecretsClientFactory support creation of secrets client for clusters

0 commit comments

Comments
 (0)