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

Commit 08364d5

Browse files
authored
Merge pull request #211 from chuckha/more-test-cleanup
🐛 Test and logic fixes
2 parents 06ae0a0 + 5d369d4 commit 08364d5

File tree

2 files changed

+110
-65
lines changed

2 files changed

+110
-65
lines changed

controllers/kubeadmconfig_controller.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,15 @@ func (r *KubeadmConfigReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result, re
267267
}
268268
if certificates != nil {
269269
hashes, err := certs.CertificateHashes(certificates.ClusterCA.Cert)
270-
if err == nil {
271-
config.Spec.JoinConfiguration.Discovery.BootstrapToken = &kubeadmv1beta1.BootstrapTokenDiscovery{
272-
CACertHashes: hashes,
270+
if err != nil {
271+
log.Error(err, "Unable to generate certificate hashes")
272+
return ctrl.Result{}, err
273+
}
274+
if hashes != nil {
275+
if config.Spec.JoinConfiguration.Discovery.BootstrapToken == nil {
276+
config.Spec.JoinConfiguration.Discovery.BootstrapToken = &kubeadmv1beta1.BootstrapTokenDiscovery{}
273277
}
278+
config.Spec.JoinConfiguration.Discovery.BootstrapToken.CACertHashes = hashes
274279
}
275280
}
276281

@@ -432,9 +437,8 @@ func (r *KubeadmConfigReconciler) reconcileDiscovery(cluster *clusterv1.Cluster,
432437
log.Info("Altering JoinConfiguration.Discovery.BootstrapToken", "Token", token)
433438
}
434439

435-
// if BootstrapToken already contains a CACertHashes or UnsafeSkipCAVerification, respect it; otherwise set for UnsafeSkipCAVerification
436-
// TODO: set CACertHashes instead of UnsafeSkipCAVerification
437-
if len(config.Spec.JoinConfiguration.Discovery.BootstrapToken.CACertHashes) == 0 && !config.Spec.JoinConfiguration.Discovery.BootstrapToken.UnsafeSkipCAVerification {
440+
// If the BootstrapToken does not contain any CACertHashes then force skip CA Verification
441+
if len(config.Spec.JoinConfiguration.Discovery.BootstrapToken.CACertHashes) == 0 {
438442
log.Info("No CAs were provided. Falling back to insecure discover method by skipping CA Cert validation")
439443
config.Spec.JoinConfiguration.Discovery.BootstrapToken.UnsafeSkipCAVerification = true
440444
}

controllers/kubeadmconfig_controller_test.go

Lines changed: 100 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ func TestKubeadmConfigReconciler_Reconcile_RequeueJoiningNodesIfControlPlaneNotI
281281
}
282282
}
283283

284+
// This generates cloud-config data but does not test the validity of it.
284285
func TestKubeadmConfigReconciler_Reconcile_GenerateCloudConfigData(t *testing.T) {
285286
cluster := newCluster("cluster")
286287
cluster.Status.InfrastructureReady = true
@@ -340,6 +341,8 @@ func TestKubeadmConfigReconciler_Reconcile_GenerateCloudConfigData(t *testing.T)
340341
}
341342
}
342343

344+
// Return an error if a worker has no JoinConfiguration defined
345+
// TODO: This logic should not error in this case. A JoinConfiguration should be autogenerated
343346
func TestKubeadmConfigReconciler_Reconcile_ErrorIfAWorkerHasNoJoinConfigurationAndTheControlPlaneIsInitialized(t *testing.T) {
344347
cluster := newCluster("cluster")
345348
cluster.Status.InfrastructureReady = true
@@ -375,7 +378,6 @@ func TestKubeadmConfigReconciler_Reconcile_ErrorIfAWorkerHasNoJoinConfigurationA
375378
}
376379

377380
// If a controlplane has an invalid JoinConfiguration then user intervention is required.
378-
// TODO: Could potentially requeue instead of error.
379381
func TestKubeadmConfigReconciler_Reconcile_ErrorIfJoiningControlPlaneHasInvalidConfiguration(t *testing.T) {
380382
cluster := newCluster("cluster")
381383
cluster.Status.InfrastructureReady = true
@@ -551,7 +553,8 @@ func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) {
551553
}
552554
}
553555

554-
func TestReconcileDiscoverySuccces(t *testing.T) {
556+
// Ensure the discovery portion of the JoinConfiguration gets generated correctly.
557+
func TestKubeadmConfigReconciler_Reconcile_DisocveryReconcileBehaviors(t *testing.T) {
555558
k := &KubeadmConfigReconciler{
556559
Log: log.Log,
557560
Client: nil,
@@ -564,13 +567,13 @@ func TestReconcileDiscoverySuccces(t *testing.T) {
564567
Status: clusterv1.ClusterStatus{
565568
APIEndpoints: []clusterv1.APIEndpoint{
566569
{
567-
Host: "foo.com",
570+
Host: "example.com",
568571
Port: 6443,
569572
},
570573
},
571574
},
572575
}
573-
var useCases = []struct {
576+
testcases := []struct {
574577
name string
575578
cluster *clusterv1.Cluster
576579
config *bootstrapv1.KubeadmConfig
@@ -592,8 +595,8 @@ func TestReconcileDiscoverySuccces(t *testing.T) {
592595
if d.BootstrapToken.Token == "" {
593596
return errors.Errorf(("BootstrapToken.Token expected, got empty string"))
594597
}
595-
if d.BootstrapToken.APIServerEndpoint != "foo.com:6443" {
596-
return errors.Errorf("BootstrapToken.APIServerEndpoint=foo.com:6443 expected, got %q", d.BootstrapToken.APIServerEndpoint)
598+
if d.BootstrapToken.APIServerEndpoint != "example.com:6443" {
599+
return errors.Errorf("BootstrapToken.APIServerEndpoint=example.com:6443 expected, got %q", d.BootstrapToken.APIServerEndpoint)
597600
}
598601
if d.BootstrapToken.UnsafeSkipCAVerification != true {
599602
return errors.Errorf("BootstrapToken.UnsafeSkipCAVerification=true expected, got false")
@@ -689,28 +692,28 @@ func TestReconcileDiscoverySuccces(t *testing.T) {
689692
},
690693
}
691694

692-
for _, rt := range useCases {
693-
rt := rt
694-
t.Run(rt.name, func(t *testing.T) {
695-
err := k.reconcileDiscovery(rt.cluster, rt.config)
695+
for _, tc := range testcases {
696+
t.Run(tc.name, func(t *testing.T) {
697+
err := k.reconcileDiscovery(tc.cluster, tc.config)
696698
if err != nil {
697699
t.Errorf("expected nil, got error %v", err)
698700
}
699701

700-
if err := rt.validateDiscovery(rt.config); err != nil {
702+
if err := tc.validateDiscovery(tc.config); err != nil {
701703
t.Fatal(err)
702704
}
703705
})
704706
}
705707
}
706708

707-
func TestReconcileDiscoveryErrors(t *testing.T) {
709+
// Test failure cases for the discovery reconcile function.
710+
func TestKubeadmConfigReconciler_Reconcile_DisocveryReconcileFailureBehaviors(t *testing.T) {
708711
k := &KubeadmConfigReconciler{
709712
Log: log.Log,
710713
Client: nil,
711714
}
712715

713-
var useCases = []struct {
716+
testcases := []struct {
714717
name string
715718
cluster *clusterv1.Cluster
716719
config *bootstrapv1.KubeadmConfig
@@ -726,24 +729,24 @@ func TestReconcileDiscoveryErrors(t *testing.T) {
726729
},
727730
}
728731

729-
for _, rt := range useCases {
730-
rt := rt
731-
t.Run(rt.name, func(t *testing.T) {
732-
err := k.reconcileDiscovery(rt.cluster, rt.config)
732+
for _, tc := range testcases {
733+
t.Run(tc.name, func(t *testing.T) {
734+
err := k.reconcileDiscovery(tc.cluster, tc.config)
733735
if err == nil {
734736
t.Error("expected error, got nil")
735737
}
736738
})
737739
}
738740
}
739741

740-
func TestReconcileTopLevelObjectSettings(t *testing.T) {
742+
// Set cluster configuration defaults based on dynamic values from the cluster object.
743+
func TestKubeadmConfigReconciler_Reconcile_DynamicDefaultsForClusterConfiguration(t *testing.T) {
741744
k := &KubeadmConfigReconciler{
742745
Log: log.Log,
743746
Client: nil,
744747
}
745748

746-
var useCases = []struct {
749+
testcases := []struct {
747750
name string
748751
cluster *clusterv1.Cluster
749752
machine *clusterv1.Machine
@@ -816,39 +819,45 @@ func TestReconcileTopLevelObjectSettings(t *testing.T) {
816819
},
817820
}
818821

819-
for _, rt := range useCases {
820-
rt := rt
821-
t.Run(rt.name, func(t *testing.T) {
822-
k.reconcileTopLevelObjectSettings(rt.cluster, rt.machine, rt.config)
822+
for _, tc := range testcases {
823+
t.Run(tc.name, func(t *testing.T) {
824+
k.reconcileTopLevelObjectSettings(tc.cluster, tc.machine, tc.config)
823825

824-
if rt.config.Spec.ClusterConfiguration.ControlPlaneEndpoint != "myControlPlaneEndpoint:6443" {
825-
t.Fatalf("expected ClusterConfiguration.ControlPlaneEndpoint %q, got %q", "myControlPlaneEndpoint:6443", rt.config.Spec.ClusterConfiguration.ControlPlaneEndpoint)
826+
if tc.config.Spec.ClusterConfiguration.ControlPlaneEndpoint != "myControlPlaneEndpoint:6443" {
827+
t.Errorf("expected ClusterConfiguration.ControlPlaneEndpoint %q, got %q", "myControlPlaneEndpoint:6443", tc.config.Spec.ClusterConfiguration.ControlPlaneEndpoint)
826828
}
827-
if rt.config.Spec.ClusterConfiguration.ClusterName != "mycluster" {
828-
t.Fatalf("expected ClusterConfiguration.ClusterName %q, got %q", "mycluster", rt.config.Spec.ClusterConfiguration.ClusterName)
829+
if tc.config.Spec.ClusterConfiguration.ClusterName != "mycluster" {
830+
t.Errorf("expected ClusterConfiguration.ClusterName %q, got %q", "mycluster", tc.config.Spec.ClusterConfiguration.ClusterName)
829831
}
830-
if rt.config.Spec.ClusterConfiguration.Networking.PodSubnet != "myPodSubnet" {
831-
t.Fatalf("expected ClusterConfiguration.Networking.PodSubnet %q, got %q", "myPodSubnet", rt.config.Spec.ClusterConfiguration.Networking.PodSubnet)
832+
if tc.config.Spec.ClusterConfiguration.Networking.PodSubnet != "myPodSubnet" {
833+
t.Errorf("expected ClusterConfiguration.Networking.PodSubnet %q, got %q", "myPodSubnet", tc.config.Spec.ClusterConfiguration.Networking.PodSubnet)
832834
}
833-
if rt.config.Spec.ClusterConfiguration.Networking.ServiceSubnet != "myServiceSubnet" {
834-
t.Fatalf("expected ClusterConfiguration.Networking.ServiceSubnet %q, got %q", "myServiceSubnet", rt.config.Spec.ClusterConfiguration.Networking.ServiceSubnet)
835+
if tc.config.Spec.ClusterConfiguration.Networking.ServiceSubnet != "myServiceSubnet" {
836+
t.Errorf("expected ClusterConfiguration.Networking.ServiceSubnet %q, got %q", "myServiceSubnet", tc.config.Spec.ClusterConfiguration.Networking.ServiceSubnet)
835837
}
836-
if rt.config.Spec.ClusterConfiguration.Networking.DNSDomain != "myDNSDomain" {
837-
t.Fatalf("expected ClusterConfiguration.Networking.DNSDomain %q, got %q", "myDNSDomain", rt.config.Spec.ClusterConfiguration.Networking.DNSDomain)
838+
if tc.config.Spec.ClusterConfiguration.Networking.DNSDomain != "myDNSDomain" {
839+
t.Errorf("expected ClusterConfiguration.Networking.DNSDomain %q, got %q", "myDNSDomain", tc.config.Spec.ClusterConfiguration.Networking.DNSDomain)
838840
}
839-
if rt.config.Spec.ClusterConfiguration.KubernetesVersion != "myversion" {
840-
t.Fatalf("expected ClusterConfiguration.KubernetesVersion %q, got %q", "myversion", rt.config.Spec.ClusterConfiguration.KubernetesVersion)
841+
if tc.config.Spec.ClusterConfiguration.KubernetesVersion != "myversion" {
842+
t.Errorf("expected ClusterConfiguration.KubernetesVersion %q, got %q", "myversion", tc.config.Spec.ClusterConfiguration.KubernetesVersion)
841843
}
842844
})
843845
}
844846
}
845847

846-
func TestCACertHashesAndUnsafeCAVerifySkip(t *testing.T) {
847-
namespace := "default" // hardcoded in the new* functions
848+
// Allow users to skip CA Verification if they *really* want to.
849+
func TestKubeadmConfigReconciler_Reconcile_AlwaysCheckCAVerificationUnlessRequestedToSkip(t *testing.T) {
850+
// Setup work for an initialized cluster
848851
clusterName := "my-cluster"
849852
cluster := newCluster(clusterName)
850853
cluster.Status.ControlPlaneInitialized = true
851854
cluster.Status.InfrastructureReady = true
855+
cluster.Status.APIEndpoints = []clusterv1.APIEndpoint{
856+
{
857+
Host: "example.com",
858+
Port: 6443,
859+
},
860+
}
852861

853862
controlPlaneMachineName := "my-machine"
854863
machine := newMachine(cluster, controlPlaneMachineName)
@@ -859,34 +868,66 @@ func TestCACertHashesAndUnsafeCAVerifySkip(t *testing.T) {
859868
controlPlaneConfigName := "my-config"
860869
config := newKubeadmConfig(machine, controlPlaneConfigName)
861870

862-
workerConfigName := "worker-join-cfg"
863-
workerConfig := newWorkerJoinKubeadmConfig(workerMachine)
864-
865871
objects := []runtime.Object{
866-
cluster, machine, workerMachine, config, workerConfig,
872+
cluster, machine, workerMachine, config,
867873
}
868874
objects = append(objects, createSecrets(t, cluster)...)
869-
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
870875

871-
reconciler := KubeadmConfigReconciler{
872-
Client: myclient,
873-
SecretsClientFactory: newFakeSecretFactory(),
874-
KubeadmInitLock: &myInitLocker{},
875-
Log: klogr.New(),
876+
testcases := []struct {
877+
name string
878+
discovery *kubeadmv1beta1.BootstrapTokenDiscovery
879+
skipCAVerification bool
880+
}{
881+
{
882+
name: "Do not skip CA verification by default",
883+
discovery: &kubeadmv1beta1.BootstrapTokenDiscovery{},
884+
skipCAVerification: false,
885+
},
886+
{
887+
name: "Skip CA verification if requested by the user",
888+
discovery: &kubeadmv1beta1.BootstrapTokenDiscovery{
889+
UnsafeSkipCAVerification: true,
890+
},
891+
skipCAVerification: true,
892+
},
893+
{
894+
// skipCAVerification should be true since no Cert Hashes are provided, but reconcile will *always* get or create certs.
895+
// TODO: Certificate get/create behavior needs to be mocked to enable this test.
896+
name: "cannot test for defaulting behavior through the reconcile function",
897+
discovery: &kubeadmv1beta1.BootstrapTokenDiscovery{
898+
CACertHashes: []string{""},
899+
},
900+
skipCAVerification: false,
901+
},
876902
}
903+
for _, tc := range testcases {
904+
t.Run(tc.name, func(t *testing.T) {
905+
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
906+
reconciler := KubeadmConfigReconciler{
907+
Client: myclient,
908+
SecretsClientFactory: newFakeSecretFactory(),
909+
KubeadmInitLock: &myInitLocker{},
910+
Log: klogr.New(),
911+
}
877912

878-
req := ctrl.Request{
879-
NamespacedName: types.NamespacedName{Name: workerConfigName, Namespace: namespace},
880-
}
881-
if _, err := reconciler.Reconcile(req); err != nil {
882-
t.Fatalf("reconciled an error: %v", err)
883-
}
884-
cfg := &bootstrapv1.KubeadmConfig{}
885-
if err := myclient.Get(context.Background(), req.NamespacedName, cfg); err != nil {
886-
t.Fatal(err)
887-
}
888-
if cfg.Spec.JoinConfiguration.Discovery.BootstrapToken.UnsafeSkipCAVerification == true {
889-
t.Fatal("Should not skip unsafe")
913+
wc := newWorkerJoinKubeadmConfig(workerMachine)
914+
wc.Spec.JoinConfiguration.Discovery.BootstrapToken = tc.discovery
915+
key := types.NamespacedName{Namespace: wc.Namespace, Name: wc.Name}
916+
if err := myclient.Create(context.Background(), wc); err != nil {
917+
t.Fatal(err)
918+
}
919+
req := ctrl.Request{NamespacedName: key}
920+
if _, err := reconciler.Reconcile(req); err != nil {
921+
t.Fatalf("reconciled an error: %v", err)
922+
}
923+
cfg := &bootstrapv1.KubeadmConfig{}
924+
if err := myclient.Get(context.Background(), key, cfg); err != nil {
925+
t.Fatal(err)
926+
}
927+
if cfg.Spec.JoinConfiguration.Discovery.BootstrapToken.UnsafeSkipCAVerification != tc.skipCAVerification {
928+
t.Fatalf("Expected skip CA verification: %v but was %v", tc.skipCAVerification, !tc.skipCAVerification)
929+
}
930+
})
890931
}
891932
}
892933

0 commit comments

Comments
 (0)