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

Commit 5d369d4

Browse files
committed
Test and logic fixes
Signed-off-by: Chuck Ha <[email protected]>
1 parent cc2b1e4 commit 5d369d4

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
@@ -280,6 +280,7 @@ func TestKubeadmConfigReconciler_Reconcile_RequeueJoiningNodesIfControlPlaneNotI
280280
}
281281
}
282282

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

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

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

553-
func TestReconcileDiscoverySuccces(t *testing.T) {
555+
// Ensure the discovery portion of the JoinConfiguration gets generated correctly.
556+
func TestKubeadmConfigReconciler_Reconcile_DisocveryReconcileBehaviors(t *testing.T) {
554557
k := &KubeadmConfigReconciler{
555558
Log: log.Log,
556559
Client: nil,
@@ -563,13 +566,13 @@ func TestReconcileDiscoverySuccces(t *testing.T) {
563566
Status: clusterv1.ClusterStatus{
564567
APIEndpoints: []clusterv1.APIEndpoint{
565568
{
566-
Host: "foo.com",
569+
Host: "example.com",
567570
Port: 6443,
568571
},
569572
},
570573
},
571574
}
572-
var useCases = []struct {
575+
testcases := []struct {
573576
name string
574577
cluster *clusterv1.Cluster
575578
config *bootstrapv1.KubeadmConfig
@@ -591,8 +594,8 @@ func TestReconcileDiscoverySuccces(t *testing.T) {
591594
if d.BootstrapToken.Token == "" {
592595
return errors.Errorf(("BootstrapToken.Token expected, got empty string"))
593596
}
594-
if d.BootstrapToken.APIServerEndpoint != "foo.com:6443" {
595-
return errors.Errorf("BootstrapToken.APIServerEndpoint=foo.com:6443 expected, got %q", d.BootstrapToken.APIServerEndpoint)
597+
if d.BootstrapToken.APIServerEndpoint != "example.com:6443" {
598+
return errors.Errorf("BootstrapToken.APIServerEndpoint=example.com:6443 expected, got %q", d.BootstrapToken.APIServerEndpoint)
596599
}
597600
if d.BootstrapToken.UnsafeSkipCAVerification != true {
598601
return errors.Errorf("BootstrapToken.UnsafeSkipCAVerification=true expected, got false")
@@ -688,28 +691,28 @@ func TestReconcileDiscoverySuccces(t *testing.T) {
688691
},
689692
}
690693

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

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

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

712-
var useCases = []struct {
715+
testcases := []struct {
713716
name string
714717
cluster *clusterv1.Cluster
715718
config *bootstrapv1.KubeadmConfig
@@ -725,24 +728,24 @@ func TestReconcileDiscoveryErrors(t *testing.T) {
725728
},
726729
}
727730

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

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

745-
var useCases = []struct {
748+
testcases := []struct {
746749
name string
747750
cluster *clusterv1.Cluster
748751
machine *clusterv1.Machine
@@ -815,39 +818,45 @@ func TestReconcileTopLevelObjectSettings(t *testing.T) {
815818
},
816819
}
817820

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

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

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

852861
controlPlaneMachineName := "my-machine"
853862
machine := newMachine(cluster, controlPlaneMachineName)
@@ -858,34 +867,66 @@ func TestCACertHashesAndUnsafeCAVerifySkip(t *testing.T) {
858867
controlPlaneConfigName := "my-config"
859868
config := newKubeadmConfig(machine, controlPlaneConfigName)
860869

861-
workerConfigName := "worker-join-cfg"
862-
workerConfig := newWorkerJoinKubeadmConfig(workerMachine)
863-
864870
objects := []runtime.Object{
865-
cluster, machine, workerMachine, config, workerConfig,
871+
cluster, machine, workerMachine, config,
866872
}
867873
objects = append(objects, createSecrets(t, cluster)...)
868-
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
869874

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

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

0 commit comments

Comments
 (0)