diff --git a/controllers/controllers_suite_test.go b/controllers/controllers_suite_test.go index 423ba28ad..82f3f745d 100644 --- a/controllers/controllers_suite_test.go +++ b/controllers/controllers_suite_test.go @@ -248,7 +248,11 @@ func getDefaultHetznerBareMetalMachineSpec() infrav1.HetznerBareMetalMachineSpec } func isPresentAndFalseWithReason(key types.NamespacedName, getter conditions.Getter, condition clusterv1.ConditionType, reason string) bool { - ExpectWithOffset(1, testEnv.Get(ctx, key, getter)).To(Succeed()) + err := testEnv.Get(ctx, key, getter) + if err != nil { + return false + } + if !conditions.Has(getter, condition) { return false } @@ -258,7 +262,11 @@ func isPresentAndFalseWithReason(key types.NamespacedName, getter conditions.Get } func isPresentAndTrue(key types.NamespacedName, getter conditions.Getter, condition clusterv1.ConditionType) bool { - ExpectWithOffset(1, testEnv.Get(ctx, key, getter)).To(Succeed()) + err := testEnv.Get(ctx, key, getter) + if err != nil { + return false + } + if !conditions.Has(getter, condition) { return false } diff --git a/controllers/hcloudmachine_controller_test.go b/controllers/hcloudmachine_controller_test.go index a5512c49d..c04fe6a26 100644 --- a/controllers/hcloudmachine_controller_test.go +++ b/controllers/hcloudmachine_controller_test.go @@ -23,7 +23,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" @@ -495,25 +494,6 @@ var _ = Describe("Hetzner secret", func() { AfterEach(func() { Expect(testEnv.Cleanup(ctx, hetznerCluster, capiCluster, hcloudMachine, capiMachine, hetznerSecret)).To(Succeed()) - - Eventually(func() bool { - if err := testEnv.Get(ctx, client.ObjectKey{Namespace: hetznerSecret.Namespace, Name: hetznerSecret.Name}, hetznerSecret); err != nil && apierrors.IsNotFound(err) { - return true - } else if err != nil { - return false - } - // Secret still there, so the finalizers have not been removed. Patch to remove them. - ph, err := patch.NewHelper(hetznerSecret, testEnv) - Expect(err).ShouldNot(HaveOccurred()) - hetznerSecret.Finalizers = nil - Expect(ph.Patch(ctx, hetznerSecret, patch.WithStatusObservedGeneration{})).To(Succeed()) - // Should delete secret - if err := testEnv.Delete(ctx, hetznerSecret); err != nil && apierrors.IsNotFound(err) { - // Has been deleted already - return true - } - return false - }, time.Second, time.Second).Should(BeTrue()) }) DescribeTable("test different hetzner secret", diff --git a/controllers/hetznercluster_controller_test.go b/controllers/hetznercluster_controller_test.go index 4f3d1238f..2b3255c70 100644 --- a/controllers/hetznercluster_controller_test.go +++ b/controllers/hetznercluster_controller_test.go @@ -25,7 +25,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" @@ -39,89 +38,20 @@ import ( ) var _ = Describe("Hetzner ClusterReconciler", func() { - It("should create a basic cluster", func() { - // Create the secret - hetznerSecret := getDefaultHetznerSecret("default") - Expect(testEnv.Create(ctx, hetznerSecret)).To(Succeed()) - defer func() { - Expect(testEnv.Cleanup(ctx, hetznerSecret)).To(Succeed()) - }() - - // Create the HetznerCluster object - instance := &infrav1.HetznerCluster{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "hetzner-test1", - Namespace: "default", - }, - Spec: getDefaultHetznerClusterSpec(), - } - Expect(testEnv.Create(ctx, instance)).To(Succeed()) - defer func() { - Expect(testEnv.Delete(ctx, instance)).To(Succeed()) - }() - - key := client.ObjectKey{Namespace: instance.Namespace, Name: instance.Name} - - // Create capi cluster - capiCluster := &clusterv1.Cluster{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "test1-", - Namespace: "default", - Finalizers: []string{clusterv1.ClusterFinalizer}, - }, - Spec: clusterv1.ClusterSpec{ - InfrastructureRef: &corev1.ObjectReference{ - APIVersion: infrav1.GroupVersion.String(), - Kind: "HetznerCluster", - Name: instance.Name, - }, - }, - } - Expect(testEnv.Create(ctx, capiCluster)).To(Succeed()) - defer func() { - Expect(testEnv.Cleanup(ctx, capiCluster)).To(Succeed()) - }() - - // Make sure the HetznerCluster exists. - Eventually(func() error { - return testEnv.Get(ctx, key, instance) - }, timeout).Should(BeNil()) - - By("setting the OwnerRef on the HetznerCluster") - // Set owner reference to Hetzner cluster - Eventually(func() error { - ph, err := patch.NewHelper(instance, testEnv) - Expect(err).ShouldNot(HaveOccurred()) - instance.OwnerReferences = append(instance.OwnerReferences, metav1.OwnerReference{ - Kind: "Cluster", - APIVersion: clusterv1.GroupVersion.String(), - Name: capiCluster.Name, - UID: capiCluster.UID, - }) - return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) - }, timeout).Should(BeNil()) - - // Check whether finalizer has been set for HetznerCluster - Eventually(func() bool { - if err := testEnv.Get(ctx, key, instance); err != nil { - return false - } - return len(instance.Finalizers) > 0 - }, timeout, time.Second).Should(BeTrue()) - }) - - Context("load balancer", func() { + Context("cluster tests", func() { var ( - err error - namespace string - testNs *corev1.Namespace - hetznerSecret *corev1.Secret - bootstrapSecret *corev1.Secret + err error + namespace string + testNs *corev1.Namespace instance *infrav1.HetznerCluster capiCluster *clusterv1.Cluster - lbName string + hetznerSecret *corev1.Secret + + key client.ObjectKey + lbName string + hetznerClusterName string ) BeforeEach(func() { testNs, err = testEnv.CreateNamespace(ctx, "lb-attachment") @@ -130,11 +60,7 @@ var _ = Describe("Hetzner ClusterReconciler", func() { lbName = utils.GenerateName(nil, "myloadbalancer") - // Create the secret - hetznerSecret = getDefaultHetznerSecret(namespace) - Expect(testEnv.Create(ctx, hetznerSecret)).To(Succeed()) - - hetznerClusterName := utils.GenerateName(nil, "hetzner-test1") + hetznerClusterName = utils.GenerateName(nil, "hetzner-test1") // Create capi cluster capiCluster = &clusterv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ @@ -168,71 +94,95 @@ var _ = Describe("Hetzner ClusterReconciler", func() { }, Spec: getDefaultHetznerClusterSpec(), } + + hetznerSecret = getDefaultHetznerSecret(namespace) + Expect(testEnv.Create(ctx, hetznerSecret)).To(Succeed()) + + key = client.ObjectKey{Namespace: namespace, Name: hetznerClusterName} }) AfterEach(func() { - Expect(testEnv.Cleanup(ctx, testNs, capiCluster, hetznerSecret, instance)).To(Succeed()) + Expect(testEnv.Cleanup(ctx, testNs, capiCluster, instance, hetznerSecret)).To(Succeed()) }) - It("should create load balancer and update it accordingly", func() { + It("should set the finalizer", func() { Expect(testEnv.Create(ctx, instance)).To(Succeed()) - key := client.ObjectKey{Namespace: instance.Namespace, Name: instance.Name} - Eventually(func() bool { if err := testEnv.Get(ctx, key, instance); err != nil { return false } - return isPresentAndTrue(key, instance, infrav1.LoadBalancerReadyCondition) - }, timeout).Should(BeTrue()) + return len(instance.Finalizers) > 0 + }, timeout, time.Second).Should(BeTrue()) + }) + + Context("load balancer", func() { + It("should create load balancer and update it accordingly", func() { + Expect(testEnv.Create(ctx, instance)).To(Succeed()) + + Eventually(func() bool { + return isPresentAndTrue(key, instance, infrav1.LoadBalancerReadyCondition) + }, timeout, time.Second).Should(BeTrue()) + + By("updating load balancer specs") + newLBName := "new-lb-name" + newLBType := "lb31" - By("updating load balancer specs") - newLBName := "new-lb-name" - newLBType := "lb31" - Eventually(func() error { ph, err := patch.NewHelper(instance, testEnv) Expect(err).ShouldNot(HaveOccurred()) + instance.Spec.ControlPlaneLoadBalancer.Type = newLBType - return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) - }, timeout).Should(BeNil()) - Eventually(func() error { - ph, err := patch.NewHelper(instance, testEnv) + Eventually(func() error { + return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) + }, timeout).Should(BeNil()) + + ph, err = patch.NewHelper(instance, testEnv) Expect(err).ShouldNot(HaveOccurred()) instance.Spec.ControlPlaneLoadBalancer.Name = &newLBName - return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) - }, timeout).Should(BeNil()) - - // Check in hetzner API - Eventually(func() error { - loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{ - ListOpts: hcloud.ListOpts{ - LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), - }, - }) - if err != nil { - return fmt.Errorf("failed to list load balancers: %w", err) - } - if len(loadBalancers) > 1 { - return fmt.Errorf("there are multiple load balancers found: %v", loadBalancers) - } - if len(loadBalancers) == 0 { - return fmt.Errorf("no load balancer found") - } - lb := loadBalancers[0] - if lb.Name != newLBName { - return fmt.Errorf("wrong name. Want %s, got %s", newLBName, lb.Name) - } - if lb.LoadBalancerType.Name != newLBType { - return fmt.Errorf("wrong name. Want %s, got %s", newLBType, lb.LoadBalancerType.Name) - } - return nil - }, timeout).Should(BeNil()) + Eventually(func() error { + return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) + }, timeout).Should(BeNil()) + + // Check in hetzner API + Eventually(func() error { + loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{ + ListOpts: hcloud.ListOpts{ + LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), + }, + }) + if err != nil { + return fmt.Errorf("failed to list load balancers: %w", err) + } + if len(loadBalancers) > 1 { + return fmt.Errorf("there are multiple load balancers found: %v", loadBalancers) + } + if len(loadBalancers) == 0 { + return fmt.Errorf("no load balancer found") + } + lb := loadBalancers[0] + + if lb.Name != newLBName { + return fmt.Errorf("wrong name. Want %s, got %s", newLBName, lb.Name) + } + if lb.LoadBalancerType.Name != newLBType { + return fmt.Errorf("wrong name. Want %s, got %s", newLBType, lb.LoadBalancerType.Name) + } + return nil + }, timeout).Should(BeNil()) + }) + + It("should update extra targets", func() { + Expect(testEnv.Create(ctx, instance)).To(Succeed()) + + Eventually(func() bool { + return isPresentAndTrue(key, instance, infrav1.LoadBalancerReadyCondition) + }, timeout).Should(BeTrue()) + + By("adding additional extra services") - By("Getting additional extra services") - Eventually(func() error { ph, err := patch.NewHelper(instance, testEnv) Expect(err).ShouldNot(HaveOccurred()) instance.Spec.ControlPlaneLoadBalancer.ExtraServices = append(instance.Spec.ControlPlaneLoadBalancer.ExtraServices, @@ -241,32 +191,34 @@ var _ = Describe("Hetzner ClusterReconciler", func() { ListenPort: 8134, Protocol: "tcp", }) - return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) - }, timeout).Should(BeNil()) - Eventually(func() int { - loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{ - ListOpts: hcloud.ListOpts{ - LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), - }, - }) - if err != nil { - return -1 - } - if len(loadBalancers) > 1 { - return -2 - } - if len(loadBalancers) == 0 { - return -3 - } - lb := loadBalancers[0] + Eventually(func() error { + return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) + }, timeout).Should(BeNil()) - return len(lb.Services) - }, timeout).Should(Equal(len(instance.Spec.ControlPlaneLoadBalancer.ExtraServices))) + Eventually(func() int { + loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{ + ListOpts: hcloud.ListOpts{ + LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), + }, + }) + if err != nil { + return -1 + } + if len(loadBalancers) > 1 { + return -2 + } + if len(loadBalancers) == 0 { + return -3 + } + lb := loadBalancers[0] - By("Getting reducing extra targets") - Eventually(func() error { - ph, err := patch.NewHelper(instance, testEnv) + return len(lb.Services) + }, timeout).Should(Equal(len(instance.Spec.ControlPlaneLoadBalancer.ExtraServices))) + + By("reducing extra targets") + + ph, err = patch.NewHelper(instance, testEnv) Expect(err).ShouldNot(HaveOccurred()) instance.Spec.ControlPlaneLoadBalancer.ExtraServices = []infrav1.LoadBalancerServiceSpec{ { @@ -275,386 +227,178 @@ var _ = Describe("Hetzner ClusterReconciler", func() { Protocol: "tcp", }, } - return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) - }, timeout).Should(BeNil()) - Eventually(func() int { - loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{ - ListOpts: hcloud.ListOpts{ - LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), - }, - }) - if err != nil { - return -1 - } - if len(loadBalancers) > 1 { - return -2 - } - if len(loadBalancers) == 0 { - return -3 - } - lb := loadBalancers[0] + Eventually(func() error { + return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) + }, timeout).Should(BeNil()) + + Eventually(func() int { + loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{ + ListOpts: hcloud.ListOpts{ + LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), + }, + }) + if err != nil { + return -1 + } + if len(loadBalancers) > 1 { + return -2 + } + if len(loadBalancers) == 0 { + return -3 + } + lb := loadBalancers[0] - return len(lb.Services) - }, timeout).Should(Equal(len(instance.Spec.ControlPlaneLoadBalancer.ExtraServices))) + return len(lb.Services) + }, timeout).Should(Equal(len(instance.Spec.ControlPlaneLoadBalancer.ExtraServices))) - By("Getting removing extra targets") - Eventually(func() error { - ph, err := patch.NewHelper(instance, testEnv) + By("removing extra targets") + + ph, err = patch.NewHelper(instance, testEnv) Expect(err).ShouldNot(HaveOccurred()) instance.Spec.ControlPlaneLoadBalancer.ExtraServices = nil - return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) - }, timeout).Should(BeNil()) - Eventually(func() int { - loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{ - ListOpts: hcloud.ListOpts{ - LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), - }, - }) - if err != nil { - return -1 - } - if len(loadBalancers) > 1 { - return -2 - } - if len(loadBalancers) == 0 { - return -3 - } - lb := loadBalancers[0] + Eventually(func() error { + return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) + }, timeout).Should(BeNil()) - return len(lb.Services) - }, timeout).Should(Equal(len(instance.Spec.ControlPlaneLoadBalancer.ExtraServices))) - }) - - It("should not create load balancer if disabled and the cluster should get ready", func() { - // Create the bootstrap secret - bootstrapSecret = getDefaultBootstrapSecret(namespace) - Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) - - defer func() { - Expect(testEnv.Delete(ctx, bootstrapSecret)).To(Succeed()) - }() + Eventually(func() int { + loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{ + ListOpts: hcloud.ListOpts{ + LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), + }, + }) + if err != nil { + return -1 + } + if len(loadBalancers) > 1 { + return -2 + } + if len(loadBalancers) == 0 { + return -3 + } + lb := loadBalancers[0] - instance.Spec.ControlPlaneLoadBalancer.Enabled = false - instance.Spec.ControlPlaneEndpoint = &clusterv1.APIEndpoint{ - Host: "my.test.host", - Port: 6443, - } - Expect(testEnv.Create(ctx, instance)).To(Succeed()) + return len(lb.Services) + }, timeout).Should(Equal(len(instance.Spec.ControlPlaneLoadBalancer.ExtraServices))) + }) - key := client.ObjectKey{Namespace: instance.Namespace, Name: instance.Name} - Eventually(func() bool { - if err := testEnv.Get(ctx, key, instance); err != nil { - return false + It("should not create load balancer if disabled and the cluster should get ready", func() { + instance.Spec.ControlPlaneLoadBalancer.Enabled = false + instance.Spec.ControlPlaneEndpoint = &clusterv1.APIEndpoint{ + Host: "my.test.host", + Port: 6443, } + Expect(testEnv.Create(ctx, instance)).To(Succeed()) - return instance.Status.ControlPlaneLoadBalancer == nil && instance.Status.Ready - }, timeout, time.Second).Should(BeTrue()) - }) - - It("should take over an existing load balancer with correct name", func() { - // Create the bootstrap secret - bootstrapSecret = getDefaultBootstrapSecret(namespace) - Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) - - defer func() { - Expect(testEnv.Delete(ctx, bootstrapSecret)).To(Succeed()) - }() - - By("creating load balancer manually") - - opts := hcloud.LoadBalancerCreateOpts{ - Name: lbName, - Algorithm: &hcloud.LoadBalancerAlgorithm{Type: hcloud.LoadBalancerAlgorithmTypeLeastConnections}, - LoadBalancerType: &hcloud.LoadBalancerType{Name: "mytype"}, - } - - _, err := hcloudClient.CreateLoadBalancer(ctx, opts) - Expect(err).To(BeNil()) + Eventually(func() bool { + if err := testEnv.Get(ctx, key, instance); err != nil { + return false + } - By("creating cluster object") - instance.Spec.ControlPlaneLoadBalancer.Name = &lbName - Expect(testEnv.Create(ctx, instance)).To(Succeed()) + return instance.Status.ControlPlaneLoadBalancer == nil && instance.Status.Ready + }, timeout, time.Second).Should(BeTrue()) + }) - By("checking that cluster is ready") - key := client.ObjectKey{Namespace: instance.Namespace, Name: instance.Name} + It("should take over an existing load balancer with correct name", func() { + By("creating load balancer manually") - Eventually(func() bool { - var foundInstance infrav1.HetznerCluster - if err := testEnv.Get(ctx, key, &foundInstance); err != nil { - return false + opts := hcloud.LoadBalancerCreateOpts{ + Name: lbName, + Algorithm: &hcloud.LoadBalancerAlgorithm{Type: hcloud.LoadBalancerAlgorithmTypeLeastConnections}, + LoadBalancerType: &hcloud.LoadBalancerType{Name: "mytype"}, } - return isPresentAndTrue(key, instance, infrav1.LoadBalancerReadyCondition) - }, timeout, time.Second).Should(BeTrue()) + _, err := hcloudClient.CreateLoadBalancer(ctx, opts) + Expect(err).To(BeNil()) - By("checking that load balancer has label set") - loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{Name: lbName}) - Expect(err).To(BeNil()) - Expect(loadBalancers).To(HaveLen(1)) + By("creating cluster object") - value, found := loadBalancers[0].Labels[instance.ClusterTagKey()] - Expect(found).To(BeTrue()) - Expect(value).To(Equal(string(infrav1.ResourceLifecycleOwned))) - }) + instance.Spec.ControlPlaneLoadBalancer.Name = &lbName + Expect(testEnv.Create(ctx, instance)).To(Succeed()) - It("should set the appropriate condition if a named load balancer is taken by another cluster", func() { - // Create the bootstrap secret - bootstrapSecret = getDefaultBootstrapSecret(namespace) - Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) + By("checking that cluster is ready") - defer func() { - Expect(testEnv.Delete(ctx, bootstrapSecret)).To(Succeed()) - }() - - By("creating load balancer manually") - labelsOwnedByOtherCluster := map[string]string{instance.ClusterTagKey() + "s": string(infrav1.ResourceLifecycleOwned)} - opts := hcloud.LoadBalancerCreateOpts{ - Name: lbName, - Algorithm: &hcloud.LoadBalancerAlgorithm{Type: hcloud.LoadBalancerAlgorithmTypeLeastConnections}, - LoadBalancerType: &hcloud.LoadBalancerType{Name: "mytype"}, - Labels: labelsOwnedByOtherCluster, - } + Eventually(func() bool { + return isPresentAndTrue(key, instance, infrav1.LoadBalancerReadyCondition) + }, timeout, time.Second).Should(BeTrue()) - _, err := hcloudClient.CreateLoadBalancer(ctx, opts) - Expect(err).To(BeNil()) + By("checking that load balancer has label set") - By("creating cluster object") - instance.Spec.ControlPlaneLoadBalancer.Name = &lbName - Expect(testEnv.Create(ctx, instance)).To(Succeed()) + loadBalancers, err := hcloudClient.ListLoadBalancers(ctx, hcloud.LoadBalancerListOpts{Name: lbName}) + Expect(err).To(BeNil()) + Expect(loadBalancers).To(HaveLen(1)) - By("checking that cluster is ready") - key := client.ObjectKey{Namespace: instance.Namespace, Name: instance.Name} + value, found := loadBalancers[0].Labels[instance.ClusterTagKey()] + Expect(found).To(BeTrue()) + Expect(value).To(Equal(string(infrav1.ResourceLifecycleOwned))) + }) - Eventually(func() bool { - var foundInstance infrav1.HetznerCluster - if err := testEnv.Get(ctx, key, &foundInstance); err != nil { - return false + It("should set the appropriate condition if a named load balancer is taken by another cluster", func() { + By("creating load balancer manually") + labelsOwnedByOtherCluster := map[string]string{instance.ClusterTagKey() + "s": string(infrav1.ResourceLifecycleOwned)} + opts := hcloud.LoadBalancerCreateOpts{ + Name: lbName, + Algorithm: &hcloud.LoadBalancerAlgorithm{Type: hcloud.LoadBalancerAlgorithmTypeLeastConnections}, + LoadBalancerType: &hcloud.LoadBalancerType{Name: "mytype"}, + Labels: labelsOwnedByOtherCluster, } - return isPresentAndFalseWithReason(key, instance, infrav1.LoadBalancerReadyCondition, infrav1.LoadBalancerFailedToOwnReason) - }, timeout, time.Second).Should(BeTrue()) - }) - - It("should set the appropriate condition if a named load balancer is not found", func() { - // Create the bootstrap secret - bootstrapSecret = getDefaultBootstrapSecret(namespace) - Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) - - defer func() { - Expect(testEnv.Delete(ctx, bootstrapSecret)).To(Succeed()) - }() - - By("creating cluster object") - instance.Spec.ControlPlaneLoadBalancer.Name = &lbName - Expect(testEnv.Create(ctx, instance)).To(Succeed()) + _, err := hcloudClient.CreateLoadBalancer(ctx, opts) + Expect(err).To(BeNil()) - By("checking that cluster has condition set") - key := client.ObjectKey{Namespace: instance.Namespace, Name: instance.Name} + By("creating cluster object") - Eventually(func() bool { - var foundInstance infrav1.HetznerCluster - if err := testEnv.Get(ctx, key, &foundInstance); err != nil { - return false - } + instance.Spec.ControlPlaneLoadBalancer.Name = &lbName + Expect(testEnv.Create(ctx, instance)).To(Succeed()) - return isPresentAndFalseWithReason(key, instance, infrav1.LoadBalancerReadyCondition, infrav1.LoadBalancerFailedToOwnReason) - }, timeout, time.Second).Should(BeTrue()) - }) - }) + By("checking that cluster is ready") - Context("For HetznerMachines belonging to the cluster", func() { - var ( - namespace string - testNs *corev1.Namespace - hetznerSecret *corev1.Secret - bootstrapSecret *corev1.Secret - ) + Eventually(func() bool { + return isPresentAndFalseWithReason(key, instance, infrav1.LoadBalancerReadyCondition, infrav1.LoadBalancerFailedToOwnReason) + }, timeout, time.Second).Should(BeTrue()) + }) - BeforeEach(func() { - var err error - testNs, err = testEnv.CreateNamespace(ctx, "hetzner-owner-ref") - Expect(err).NotTo(HaveOccurred()) - namespace = testNs.Name + It("should set the appropriate condition if a named load balancer is not found", func() { + By("creating cluster object") - // Create the hetzner secret - hetznerSecret = getDefaultHetznerSecret(namespace) - Expect(testEnv.Create(ctx, hetznerSecret)).To(Succeed()) - // Create the bootstrap secret - bootstrapSecret = getDefaultBootstrapSecret(namespace) - Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) - }) - - AfterEach(func() { - Expect(testEnv.Delete(ctx, bootstrapSecret)).To(Succeed()) - Expect(testEnv.Delete(ctx, hetznerSecret)).To(Succeed()) - Expect(testEnv.Delete(ctx, testNs)).To(Succeed()) - }) + instance.Spec.ControlPlaneLoadBalancer.Name = &lbName + Expect(testEnv.Create(ctx, instance)).To(Succeed()) - It("sets owner references to those machines", func() { - // Create the HetznerCluster object - instance := &infrav1.HetznerCluster{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "test1-", - Namespace: namespace, - }, - Spec: getDefaultHetznerClusterSpec(), - } - Expect(testEnv.Create(ctx, instance)).To(Succeed()) - defer func() { - Expect(testEnv.Cleanup(ctx, instance)).To(Succeed()) - }() - capiCluster := &clusterv1.Cluster{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "capi-test1-", - Namespace: namespace, - Finalizers: []string{clusterv1.ClusterFinalizer}, - }, - Spec: clusterv1.ClusterSpec{ - InfrastructureRef: &corev1.ObjectReference{ - APIVersion: infrav1.GroupVersion.String(), - Kind: "HetznerCluster", - Name: instance.Name, - Namespace: namespace, - }, - }, - } - Expect(testEnv.Create(ctx, capiCluster)).To(Succeed()) - defer func() { - Expect(testEnv.Cleanup(ctx, capiCluster)).To(Succeed()) - }() - - // Make sure the HCloudCluster exists. - Eventually(func() error { - return testEnv.Get(ctx, client.ObjectKey{Namespace: namespace, Name: instance.Name}, instance) - }, timeout).Should(BeNil()) - - // Create machines - machineCount := 3 - for i := 0; i < machineCount; i++ { - Expect(createHCloudMachine(ctx, testEnv, namespace, capiCluster.Name)).To(Succeed()) - } + By("checking that cluster has condition set") - // Set owner reference to HetznerCluster - Eventually(func() bool { - ph, err := patch.NewHelper(instance, testEnv) - Expect(err).ShouldNot(HaveOccurred()) - instance.OwnerReferences = append(instance.OwnerReferences, metav1.OwnerReference{ - Kind: "Cluster", - APIVersion: clusterv1.GroupVersion.String(), - Name: capiCluster.Name, - UID: capiCluster.UID, - }) - Expect(ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{})).ShouldNot(HaveOccurred()) - return true - }, timeout).Should(BeTrue()) - - By("checking for presence of HCloudMachine objects") - // Check if machines have been created - Eventually(func() int { - servers, err := hcloudClient.ListServers(ctx, hcloud.ServerListOpts{ - ListOpts: hcloud.ListOpts{ - LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), - }, - }) - if err != nil { - return -1 - } - return len(servers) - }, timeout).Should(Equal(machineCount)) + Eventually(func() bool { + return isPresentAndFalseWithReason(key, instance, infrav1.LoadBalancerReadyCondition, infrav1.LoadBalancerFailedToOwnReason) + }, timeout, time.Second).Should(BeTrue()) + }) }) - }) - - Context("Placement groups", func() { - var ( - namespace string - testNs *corev1.Namespace - hetznerSecret *corev1.Secret - bootstrapSecret *corev1.Secret - - instance *infrav1.HetznerCluster - capiCluster *clusterv1.Cluster - ) - - BeforeEach(func() { - var err error - testNs, err = testEnv.CreateNamespace(ctx, "ns-placement-groups") - Expect(err).NotTo(HaveOccurred()) - namespace = testNs.Name - - // Create the hetzner secret - hetznerSecret = getDefaultHetznerSecret(namespace) - Expect(testEnv.Create(ctx, hetznerSecret)).To(Succeed()) - // Create the bootstrap secret - bootstrapSecret = getDefaultBootstrapSecret(namespace) - Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) - hetznerClusterName := utils.GenerateName(nil, "test1-") + Context("HetznerMachines belonging to the cluster", func() { + var bootstrapSecret *corev1.Secret - capiCluster = &clusterv1.Cluster{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "capi-test1-", - Namespace: namespace, - Finalizers: []string{clusterv1.ClusterFinalizer}, - }, - Spec: clusterv1.ClusterSpec{ - InfrastructureRef: &corev1.ObjectReference{ - APIVersion: infrav1.GroupVersion.String(), - Kind: "HetznerCluster", - Name: hetznerClusterName, - Namespace: namespace, - }, - }, - } - Expect(testEnv.Create(ctx, capiCluster)).To(Succeed()) - - instance = &infrav1.HetznerCluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: hetznerClusterName, - Namespace: namespace, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "cluster.x-k8s.io/v1beta1", - Kind: "Cluster", - Name: capiCluster.Name, - UID: capiCluster.UID, - }, - }, - }, - Spec: getDefaultHetznerClusterSpec(), - } - }) + BeforeEach(func() { + bootstrapSecret = getDefaultBootstrapSecret(namespace) + Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) + }) - AfterEach(func() { - Expect(testEnv.Delete(ctx, bootstrapSecret)).To(Succeed()) - Expect(testEnv.Delete(ctx, hetznerSecret)).To(Succeed()) - Expect(testEnv.Delete(ctx, capiCluster)).To(Succeed()) - Expect(testEnv.Delete(ctx, testNs)).To(Succeed()) - }) + AfterEach(func() { + Expect(testEnv.Cleanup(ctx, bootstrapSecret)).To(Succeed()) + }) - DescribeTable("create and delete placement groups without error", - func(placementGroups []infrav1.HCloudPlacementGroupSpec) { - // Create the HetznerCluster object - instance.Spec.HCloudPlacementGroups = placementGroups + It("sets owner references to those machines", func() { Expect(testEnv.Create(ctx, instance)).To(Succeed()) - defer func() { - Expect(testEnv.Cleanup(ctx, instance)).To(Succeed()) - }() - key := client.ObjectKey{Namespace: namespace, Name: instance.Name} + By("creating hcloudmachine objects") - Eventually(func() bool { - if err := testEnv.Get(ctx, key, instance); err != nil { - return false - } - return isPresentAndTrue(key, instance, infrav1.PlacementGroupsSyncedCondition) - }, timeout).Should(BeTrue()) + machineCount := 3 + for i := 0; i < machineCount; i++ { + Expect(createCapiAndHcloudMachines(ctx, testEnv, namespace, capiCluster.Name)).To(Succeed()) + } + + By("checking labels of HCloudMachine objects") - By("checking for presence of HCloudPlacementGroup objects") - // Check if placement groups have been created Eventually(func() int { - pgs, err := hcloudClient.ListPlacementGroups(ctx, hcloud.PlacementGroupListOpts{ + servers, err := hcloudClient.ListServers(ctx, hcloud.ServerListOpts{ ListOpts: hcloud.ListOpts{ LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), }, @@ -662,36 +406,34 @@ var _ = Describe("Hetzner ClusterReconciler", func() { if err != nil { return -1 } - return len(pgs) - }, timeout).Should(Equal(len(placementGroups))) - }, - Entry("placement groups", []infrav1.HCloudPlacementGroupSpec{ - { - Name: defaultPlacementGroupName, - Type: "spread", - }, - { - Name: "md-0", - Type: "spread", - }, - }), - Entry("no placement groups", []infrav1.HCloudPlacementGroupSpec{}), - ) + return len(servers) + }, timeout).Should(Equal(machineCount)) + }) + }) + + Context("Placement groups", func() { + var bootstrapSecret *corev1.Secret - Describe("update placement groups", func() { BeforeEach(func() { - Expect(testEnv.Create(ctx, instance)).To(Succeed()) + // Create the bootstrap secret + bootstrapSecret = getDefaultBootstrapSecret(namespace) + Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) }) + AfterEach(func() { - Expect(testEnv.Cleanup(ctx, instance)).To(Succeed()) + Expect(testEnv.Cleanup(ctx, bootstrapSecret)).To(Succeed()) }) - DescribeTable("update placement groups", - func(newPlacementGroupSpec []infrav1.HCloudPlacementGroupSpec) { - ph, err := patch.NewHelper(instance, testEnv) - Expect(err).ShouldNot(HaveOccurred()) - instance.Spec.HCloudPlacementGroups = newPlacementGroupSpec - Expect(ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{})).To(Succeed()) + DescribeTable("create and delete placement groups without error", + func(placementGroups []infrav1.HCloudPlacementGroupSpec) { + instance.Spec.HCloudPlacementGroups = placementGroups + Expect(testEnv.Create(ctx, instance)).To(Succeed()) + + Eventually(func() bool { + return isPresentAndTrue(key, instance, infrav1.PlacementGroupsSyncedCondition) + }, timeout).Should(BeTrue()) + + By("checking for presence of HCloudPlacementGroup objects") Eventually(func() int { pgs, err := hcloudClient.ListPlacementGroups(ctx, hcloud.PlacementGroupListOpts{ @@ -703,113 +445,85 @@ var _ = Describe("Hetzner ClusterReconciler", func() { return -1 } return len(pgs) - }, timeout).Should(Equal(len(newPlacementGroupSpec))) + }, timeout).Should(Equal(len(placementGroups))) }, - Entry("one pg", []infrav1.HCloudPlacementGroupSpec{{Name: "md-0", Type: "spread"}}), - Entry("no pgs", []infrav1.HCloudPlacementGroupSpec{}), - Entry("three pgs", []infrav1.HCloudPlacementGroupSpec{ - {Name: "md-0", Type: "spread"}, - {Name: "md-1", Type: "spread"}, - {Name: "md-2", Type: "spread"}, + Entry("placement groups", []infrav1.HCloudPlacementGroupSpec{ + { + Name: defaultPlacementGroupName, + Type: "spread", + }, + { + Name: "md-0", + Type: "spread", + }, }), + Entry("no placement groups", []infrav1.HCloudPlacementGroupSpec{}), ) - }) - }) - Context("network", func() { - var ( - namespace string - testNs *corev1.Namespace - bootstrapSecret *corev1.Secret - hetznerSecret *corev1.Secret - ) - - hetznerClusterSpecWithDisabledNetwork := getDefaultHetznerClusterSpec() - hetznerClusterSpecWithDisabledNetwork.HCloudNetwork.Enabled = false - hetznerClusterSpecWithoutNetwork := getDefaultHetznerClusterSpec() - hetznerClusterSpecWithoutNetwork.HCloudNetwork = infrav1.HCloudNetworkSpec{} - BeforeEach(func() { - var err error - testNs, err = testEnv.CreateNamespace(ctx, "ns-network") - Expect(err).NotTo(HaveOccurred()) - namespace = testNs.Name + Context("update placement groups", func() { + BeforeEach(func() { + Expect(testEnv.Create(ctx, instance)).To(Succeed()) + }) - // Create the bootstrap secret - bootstrapSecret = getDefaultBootstrapSecret(namespace) - Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) - // Create the hetzner secret - hetznerSecret = getDefaultHetznerSecret(namespace) - Expect(testEnv.Create(ctx, hetznerSecret)).To(Succeed()) + DescribeTable("update placement groups", + func(newPlacementGroupSpec []infrav1.HCloudPlacementGroupSpec) { + ph, err := patch.NewHelper(instance, testEnv) + Expect(err).ShouldNot(HaveOccurred()) + + instance.Spec.HCloudPlacementGroups = newPlacementGroupSpec + + Eventually(func() error { + return ph.Patch(ctx, instance, patch.WithStatusObservedGeneration{}) + }, timeout).Should(BeNil()) + + Eventually(func() int { + pgs, err := hcloudClient.ListPlacementGroups(ctx, hcloud.PlacementGroupListOpts{ + ListOpts: hcloud.ListOpts{ + LabelSelector: utils.LabelsToLabelSelector(map[string]string{instance.ClusterTagKey(): "owned"}), + }, + }) + if err != nil { + return -1 + } + return len(pgs) + }, timeout).Should(Equal(len(newPlacementGroupSpec))) + }, + Entry("one pg", []infrav1.HCloudPlacementGroupSpec{{Name: "md-0", Type: "spread"}}), + Entry("no pgs", []infrav1.HCloudPlacementGroupSpec{}), + Entry("three pgs", []infrav1.HCloudPlacementGroupSpec{ + {Name: "md-0", Type: "spread"}, + {Name: "md-1", Type: "spread"}, + {Name: "md-2", Type: "spread"}, + }), + ) + }) }) - AfterEach(func() { - Expect(testEnv.Delete(ctx, bootstrapSecret)).To(Succeed()) - Expect(testEnv.Delete(ctx, hetznerSecret)).To(Succeed()) - Expect(testEnv.Delete(ctx, testNs)).To(Succeed()) - }) + Context("network", func() { + var bootstrapSecret *corev1.Secret - DescribeTable("toggle network", - func(hetznerClusterSpec infrav1.HetznerClusterSpec, expectedConditionState bool, expectedReason string) { - hetznerClusterName := utils.GenerateName(nil, "test1-") - capiCluster := &clusterv1.Cluster{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "capi-test1-", - Namespace: namespace, - Finalizers: []string{clusterv1.ClusterFinalizer}, - }, - Spec: clusterv1.ClusterSpec{ - InfrastructureRef: &corev1.ObjectReference{ - APIVersion: infrav1.GroupVersion.String(), - Kind: "HetznerCluster", - Name: hetznerClusterName, - Namespace: namespace, - }, - }, - } - Expect(testEnv.Create(ctx, capiCluster)).To(Succeed()) - defer func() { - Expect(testEnv.Cleanup(ctx, capiCluster)).To(Succeed()) - }() - - // Create the HetznerCluster object - instance := &infrav1.HetznerCluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: hetznerClusterName, - Namespace: namespace, - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "cluster.x-k8s.io/v1beta1", - Kind: "Cluster", - Name: capiCluster.Name, - UID: capiCluster.UID, - }, - }, - }, - Spec: hetznerClusterSpec, - } - Expect(testEnv.Create(ctx, instance)).To(Succeed()) - defer func() { - Expect(testEnv.Cleanup(ctx, instance)).To(Succeed()) - }() + BeforeEach(func() { + bootstrapSecret = getDefaultBootstrapSecret(namespace) + Expect(testEnv.Create(ctx, bootstrapSecret)).To(Succeed()) + }) - key := client.ObjectKey{Namespace: instance.Namespace, Name: instance.Name} + AfterEach(func() { + Expect(testEnv.Delete(ctx, bootstrapSecret)).To(Succeed()) + }) + + It("creates a cluster with network and gets ready", func() { + Expect(testEnv.Create(ctx, instance)).To(Succeed()) Eventually(func() bool { - if err := testEnv.Get(ctx, key, instance); err != nil { - return false - } - if expectedConditionState { - return isPresentAndTrue(key, instance, infrav1.NetworkReadyCondition) - } - return isPresentAndFalseWithReason(key, instance, infrav1.NetworkReadyCondition, expectedReason) + return isPresentAndTrue(key, instance, infrav1.NetworkReadyCondition) }, timeout).Should(BeTrue()) }, - Entry("with network", getDefaultHetznerClusterSpec(), true, ""), - ) + ) + }) }) }) -func createHCloudMachine(ctx context.Context, env *helpers.TestEnvironment, namespace, clusterName string) error { +func createCapiAndHcloudMachines(ctx context.Context, env *helpers.TestEnvironment, namespace, clusterName string) error { hcloudMachineName := utils.GenerateName(nil, "hcloud-machine") capiMachine := &clusterv1.Machine{ ObjectMeta: metav1.ObjectMeta{ @@ -861,22 +575,26 @@ func createHCloudMachine(ctx context.Context, env *helpers.TestEnvironment, name var _ = Describe("Hetzner secret", func() { var ( - hetznerCluster *infrav1.HetznerCluster - capiCluster *clusterv1.Cluster + testNs *corev1.Namespace + hetznerCluster *infrav1.HetznerCluster + capiCluster *clusterv1.Cluster + + hetznerSecret *corev1.Secret + key client.ObjectKey - hetznerSecret *corev1.Secret hetznerClusterName string ) BeforeEach(func() { var err error + testNs, err = testEnv.CreateNamespace(ctx, "hetzner-secret") Expect(err).NotTo(HaveOccurred()) hetznerClusterName = utils.GenerateName(nil, "hetzner-cluster-test") capiCluster = &clusterv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ GenerateName: "test1-", - Namespace: "default", + Namespace: testNs.Name, Finalizers: []string{clusterv1.ClusterFinalizer}, }, Spec: clusterv1.ClusterSpec{ @@ -884,7 +602,7 @@ var _ = Describe("Hetzner secret", func() { APIVersion: infrav1.GroupVersion.String(), Kind: "HetznerCluster", Name: hetznerClusterName, - Namespace: "default", + Namespace: testNs.Name, }, }, } @@ -893,7 +611,7 @@ var _ = Describe("Hetzner secret", func() { hetznerCluster = &infrav1.HetznerCluster{ ObjectMeta: metav1.ObjectMeta{ Name: hetznerClusterName, - Namespace: "default", + Namespace: testNs.Name, OwnerReferences: []metav1.OwnerReference{ { APIVersion: "cluster.x-k8s.io/v1beta1", @@ -912,65 +630,49 @@ var _ = Describe("Hetzner secret", func() { AfterEach(func() { Expect(testEnv.Cleanup(ctx, hetznerCluster, capiCluster, hetznerSecret)).To(Succeed()) - - Eventually(func() bool { - if err := testEnv.Get(ctx, client.ObjectKey{Namespace: hetznerSecret.Namespace, Name: hetznerSecret.Name}, hetznerSecret); err != nil && apierrors.IsNotFound(err) { - return true - } else if err != nil { - return false - } - // Secret still there, so the finalizers have not been removed. Patch to remove them. - ph, err := patch.NewHelper(hetznerSecret, testEnv) - Expect(err).ShouldNot(HaveOccurred()) - hetznerSecret.Finalizers = nil - Expect(ph.Patch(ctx, hetznerSecret, patch.WithStatusObservedGeneration{})).To(Succeed()) - // Should delete secret - if err := testEnv.Delete(ctx, hetznerSecret); err != nil && apierrors.IsNotFound(err) { - // Has been deleted already - return true - } - return false - }, time.Second, time.Second).Should(BeTrue()) }) DescribeTable("test different hetzner secret", - func(secret corev1.Secret, expectedReason string) { - hetznerSecret = &secret + func(secretFunc func() *corev1.Secret, expectedReason string) { + hetznerSecret = secretFunc() Expect(testEnv.Create(ctx, hetznerSecret)).To(Succeed()) Eventually(func() bool { - if err := testEnv.Get(ctx, key, hetznerCluster); err != nil { - return false - } return isPresentAndFalseWithReason(key, hetznerCluster, infrav1.HCloudTokenAvailableCondition, expectedReason) }, timeout, time.Second).Should(BeTrue()) }, - Entry("no Hetzner secret/wrong reference", corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "wrong-name", - Namespace: "default", - }, - Data: map[string][]byte{ - "hcloud": []byte("my-token"), - }, + Entry("no Hetzner secret/wrong reference", func() *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "wrong-name", + Namespace: testNs.Name, + }, + Data: map[string][]byte{ + "hcloud": []byte("my-token"), + }, + } }, infrav1.HetznerSecretUnreachableReason), - Entry("empty hcloud token", corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "hetzner-secret", - Namespace: "default", - }, - Data: map[string][]byte{ - "hcloud": []byte(""), - }, + Entry("empty hcloud token", func() *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "hetzner-secret", + Namespace: testNs.Name, + }, + Data: map[string][]byte{ + "hcloud": []byte(""), + }, + } }, infrav1.HCloudCredentialsInvalidReason), - Entry("wrong key in secret", corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "hetzner-secret", - Namespace: "default", - }, - Data: map[string][]byte{ - "wrongkey": []byte("my-token"), - }, + Entry("wrong key in secret", func() *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "hetzner-secret", + Namespace: testNs.Name, + }, + Data: map[string][]byte{ + "wrongkey": []byte("my-token"), + }, + } }, infrav1.HCloudCredentialsInvalidReason), ) }) @@ -1000,6 +702,10 @@ var _ = Describe("HetznerCluster validation", func() { } }) + It("should succeed with valid spec", func() { + Expect(testEnv.Create(ctx, hetznerCluster)).To(Succeed()) + }) + It("should fail without a wrong controlPlaneRegion name", func() { hetznerCluster.Spec.ControlPlaneRegions = append(hetznerCluster.Spec.ControlPlaneRegions, infrav1.Region("wrong-region")) Expect(testEnv.Create(ctx, hetznerCluster)).ToNot(Succeed()) @@ -1042,24 +748,24 @@ var _ = Describe("reconcileRateLimit", func() { } }) - It("returns wait== true if rate limit exceeded is set and time is not over", func() { + It("returns wait==true if rate limit exceeded is set and time is not over", func() { conditions.MarkFalse(hetznerCluster, infrav1.HetznerAPIReachableCondition, infrav1.RateLimitExceededReason, clusterv1.ConditionSeverityWarning, "") Expect(reconcileRateLimit(hetznerCluster)).To(BeTrue()) }) - It("returns wait== false if rate limit exceeded is set and time is over", func() { + It("returns wait==false if rate limit exceeded is set and time is over", func() { conditions.MarkFalse(hetznerCluster, infrav1.HetznerAPIReachableCondition, infrav1.RateLimitExceededReason, clusterv1.ConditionSeverityWarning, "") conditionList := hetznerCluster.GetConditions() conditionList[0].LastTransitionTime = metav1.NewTime(time.Now().Add(-time.Hour)) Expect(reconcileRateLimit(hetznerCluster)).To(BeFalse()) }) - It("returns wait== false if rate limit condition is set to true", func() { + It("returns wait==false if rate limit condition is set to true", func() { conditions.MarkTrue(hetznerCluster, infrav1.HetznerAPIReachableCondition) Expect(reconcileRateLimit(hetznerCluster)).To(BeFalse()) }) - It("returns wait== false if rate limit condition is not set", func() { + It("returns wait==false if rate limit condition is not set", func() { Expect(reconcileRateLimit(hetznerCluster)).To(BeFalse()) }) })