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

Commit 2786787

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

File tree

2 files changed

+111
-65
lines changed

2 files changed

+111
-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 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: 101 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 probably just return and wait for the worker to have a join configuration?
342345
func TestKubeadmConfigReconciler_Reconcile_ErrorIfAWorkerHasNoJoinConfigurationAndTheControlPlaneIsInitialized(t *testing.T) {
343346
cluster := newCluster("cluster")
344347
cluster.Status.InfrastructureReady = true
@@ -374,7 +377,7 @@ 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.
380+
// TODO: Could potentially requeue/return nothing instead of error.
378381
func TestKubeadmConfigReconciler_Reconcile_ErrorIfJoiningControlPlaneHasInvalidConfiguration(t *testing.T) {
379382
cluster := newCluster("cluster")
380383
cluster.Status.InfrastructureReady = true
@@ -550,7 +553,8 @@ func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) {
550553
}
551554
}
552555

553-
func TestReconcileDiscoverySuccces(t *testing.T) {
556+
// Ensure the discovery portion of the JoinConfiguration gets generated correctly.
557+
func TestKubeadmConfigReconciler_Reconcile_DisocveryReconcileBehaviors(t *testing.T) {
554558
k := &KubeadmConfigReconciler{
555559
Log: log.Log,
556560
Client: nil,
@@ -563,13 +567,13 @@ func TestReconcileDiscoverySuccces(t *testing.T) {
563567
Status: clusterv1.ClusterStatus{
564568
APIEndpoints: []clusterv1.APIEndpoint{
565569
{
566-
Host: "foo.com",
570+
Host: "example.com",
567571
Port: 6443,
568572
},
569573
},
570574
},
571575
}
572-
var useCases = []struct {
576+
testcases := []struct {
573577
name string
574578
cluster *clusterv1.Cluster
575579
config *bootstrapv1.KubeadmConfig
@@ -591,8 +595,8 @@ func TestReconcileDiscoverySuccces(t *testing.T) {
591595
if d.BootstrapToken.Token == "" {
592596
return errors.Errorf(("BootstrapToken.Token expected, got empty string"))
593597
}
594-
if d.BootstrapToken.APIServerEndpoint != "foo.com:6443" {
595-
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)
596600
}
597601
if d.BootstrapToken.UnsafeSkipCAVerification != true {
598602
return errors.Errorf("BootstrapToken.UnsafeSkipCAVerification=true expected, got false")
@@ -688,28 +692,28 @@ func TestReconcileDiscoverySuccces(t *testing.T) {
688692
},
689693
}
690694

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)
695+
for _, tc := range testcases {
696+
t.Run(tc.name, func(t *testing.T) {
697+
err := k.reconcileDiscovery(tc.cluster, tc.config)
695698
if err != nil {
696699
t.Errorf("expected nil, got error %v", err)
697700
}
698701

699-
if err := rt.validateDiscovery(rt.config); err != nil {
702+
if err := tc.validateDiscovery(tc.config); err != nil {
700703
t.Fatal(err)
701704
}
702705
})
703706
}
704707
}
705708

706-
func TestReconcileDiscoveryErrors(t *testing.T) {
709+
// Test failure cases for the discovery reconcile function.
710+
func TestKubeadmConfigReconciler_Reconcile_DisocveryReconcileFailureBehaviors(t *testing.T) {
707711
k := &KubeadmConfigReconciler{
708712
Log: log.Log,
709713
Client: nil,
710714
}
711715

712-
var useCases = []struct {
716+
testcases := []struct {
713717
name string
714718
cluster *clusterv1.Cluster
715719
config *bootstrapv1.KubeadmConfig
@@ -725,24 +729,24 @@ func TestReconcileDiscoveryErrors(t *testing.T) {
725729
},
726730
}
727731

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)
732+
for _, tc := range testcases {
733+
t.Run(tc.name, func(t *testing.T) {
734+
err := k.reconcileDiscovery(tc.cluster, tc.config)
732735
if err == nil {
733736
t.Error("expected error, got nil")
734737
}
735738
})
736739
}
737740
}
738741

739-
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) {
740744
k := &KubeadmConfigReconciler{
741745
Log: log.Log,
742746
Client: nil,
743747
}
744748

745-
var useCases = []struct {
749+
testcases := []struct {
746750
name string
747751
cluster *clusterv1.Cluster
748752
machine *clusterv1.Machine
@@ -815,39 +819,45 @@ func TestReconcileTopLevelObjectSettings(t *testing.T) {
815819
},
816820
}
817821

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)
822+
for _, tc := range testcases {
823+
t.Run(tc.name, func(t *testing.T) {
824+
k.reconcileTopLevelObjectSettings(tc.cluster, tc.machine, tc.config)
822825

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)
826+
if tc.config.Spec.ClusterConfiguration.ControlPlaneEndpoint != "myControlPlaneEndpoint:6443" {
827+
t.Fatalf("expected ClusterConfiguration.ControlPlaneEndpoint %q, got %q", "myControlPlaneEndpoint:6443", tc.config.Spec.ClusterConfiguration.ControlPlaneEndpoint)
825828
}
826-
if rt.config.Spec.ClusterConfiguration.ClusterName != "mycluster" {
827-
t.Fatalf("expected ClusterConfiguration.ClusterName %q, got %q", "mycluster", rt.config.Spec.ClusterConfiguration.ClusterName)
829+
if tc.config.Spec.ClusterConfiguration.ClusterName != "mycluster" {
830+
t.Fatalf("expected ClusterConfiguration.ClusterName %q, got %q", "mycluster", tc.config.Spec.ClusterConfiguration.ClusterName)
828831
}
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)
832+
if tc.config.Spec.ClusterConfiguration.Networking.PodSubnet != "myPodSubnet" {
833+
t.Fatalf("expected ClusterConfiguration.Networking.PodSubnet %q, got %q", "myPodSubnet", tc.config.Spec.ClusterConfiguration.Networking.PodSubnet)
831834
}
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)
835+
if tc.config.Spec.ClusterConfiguration.Networking.ServiceSubnet != "myServiceSubnet" {
836+
t.Fatalf("expected ClusterConfiguration.Networking.ServiceSubnet %q, got %q", "myServiceSubnet", tc.config.Spec.ClusterConfiguration.Networking.ServiceSubnet)
834837
}
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)
838+
if tc.config.Spec.ClusterConfiguration.Networking.DNSDomain != "myDNSDomain" {
839+
t.Fatalf("expected ClusterConfiguration.Networking.DNSDomain %q, got %q", "myDNSDomain", tc.config.Spec.ClusterConfiguration.Networking.DNSDomain)
837840
}
838-
if rt.config.Spec.ClusterConfiguration.KubernetesVersion != "myversion" {
839-
t.Fatalf("expected ClusterConfiguration.KubernetesVersion %q, got %q", "myversion", rt.config.Spec.ClusterConfiguration.KubernetesVersion)
841+
if tc.config.Spec.ClusterConfiguration.KubernetesVersion != "myversion" {
842+
t.Fatalf("expected ClusterConfiguration.KubernetesVersion %q, got %q", "myversion", tc.config.Spec.ClusterConfiguration.KubernetesVersion)
840843
}
841844
})
842845
}
843846
}
844847

845-
func TestCACertHashesAndUnsafeCAVerifySkip(t *testing.T) {
846-
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
847851
clusterName := "my-cluster"
848852
cluster := newCluster(clusterName)
849853
cluster.Status.ControlPlaneInitialized = true
850854
cluster.Status.InfrastructureReady = true
855+
cluster.Status.APIEndpoints = []clusterv1.APIEndpoint{
856+
{
857+
Host: "example.com",
858+
Port: 6443,
859+
},
860+
}
851861

852862
controlPlaneMachineName := "my-machine"
853863
machine := newMachine(cluster, controlPlaneMachineName)
@@ -858,34 +868,66 @@ func TestCACertHashesAndUnsafeCAVerifySkip(t *testing.T) {
858868
controlPlaneConfigName := "my-config"
859869
config := newKubeadmConfig(machine, controlPlaneConfigName)
860870

861-
workerConfigName := "worker-join-cfg"
862-
workerConfig := newWorkerJoinKubeadmConfig(workerMachine)
863-
864871
objects := []runtime.Object{
865-
cluster, machine, workerMachine, config, workerConfig,
872+
cluster, machine, workerMachine, config,
866873
}
867874
objects = append(objects, createSecrets(t, cluster)...)
868-
myclient := fake.NewFakeClientWithScheme(setupScheme(), objects...)
869875

870-
reconciler := KubeadmConfigReconciler{
871-
Client: myclient,
872-
SecretsClientFactory: newFakeSecretFactory(),
873-
KubeadmInitLock: &myInitLocker{},
874-
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+
// This 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+
},
875902
}
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+
}
876912

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")
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+
})
889931
}
890932
}
891933

0 commit comments

Comments
 (0)