From e0e93411bbee4e22698e2d7b086e45c40bc43f3e Mon Sep 17 00:00:00 2001 From: Michael Nairn Date: Mon, 13 Nov 2023 15:43:58 +0000 Subject: [PATCH 1/2] Split dnspolicy controller tests Created separate files for dnspolicy controller tests: dnspolicy_controller_test.go - DNSPolicy common lifecycle tests dnspolicy_controller_health_checks_test.go - DNSPolicy Health check specific tests dnspolicy_controller_multi_cluster_test.go - DNSPolicy Multi Cluster (Gateway with MGC status address) specific tests dnspolicy_controller_single_cluster_test.go - DNSPolicy Single Cluster (Gateway with standard status address) specific tests --- test/gateway_integration/suite_test.go | 2 +- ...dnspolicy_controller_health_checks_test.go | 599 ++++++++ ...dnspolicy_controller_multi_cluster_test.go | 923 ++++++++++++ ...nspolicy_controller_single_cluster_test.go | 255 ++++ .../dnspolicy_controller_test.go | 1334 ++--------------- test/policy_integration/suite_test.go | 2 +- .../tlspolicy_controller_test.go | 6 - 7 files changed, 1942 insertions(+), 1179 deletions(-) create mode 100644 test/policy_integration/dnspolicy_controller_health_checks_test.go create mode 100644 test/policy_integration/dnspolicy_controller_multi_cluster_test.go create mode 100644 test/policy_integration/dnspolicy_controller_single_cluster_test.go diff --git a/test/gateway_integration/suite_test.go b/test/gateway_integration/suite_test.go index ca0f23ac..a9c96dd8 100644 --- a/test/gateway_integration/suite_test.go +++ b/test/gateway_integration/suite_test.go @@ -64,7 +64,7 @@ func testClient() client.Client { return k8sClient } func TestAPIs(t *testing.T) { RegisterFailHandler(Fail) - RunSpecs(t, "Controller Suite") + RunSpecs(t, "Gateway Controller Suite") } var _ = BeforeSuite(func() { diff --git a/test/policy_integration/dnspolicy_controller_health_checks_test.go b/test/policy_integration/dnspolicy_controller_health_checks_test.go new file mode 100644 index 00000000..103e2747 --- /dev/null +++ b/test/policy_integration/dnspolicy_controller_health_checks_test.go @@ -0,0 +1,599 @@ +//go:build integration + +package policy_integration + +import ( + "context" + "fmt" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gstruct" + v1 "open-cluster-management.io/api/cluster/v1" + + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + + "github.com/Kuadrant/multicluster-gateway-controller/pkg/apis/v1alpha1" + mgcgateway "github.com/Kuadrant/multicluster-gateway-controller/pkg/controllers/gateway" + "github.com/Kuadrant/multicluster-gateway-controller/pkg/dns" + testutil "github.com/Kuadrant/multicluster-gateway-controller/test/util" +) + +var _ = Describe("DNSPolicy Health Checks", Ordered, func() { + + var gatewayClass *gatewayv1beta1.GatewayClass + var managedZone *v1alpha1.ManagedZone + var testNamespace string + var dnsPolicyBuilder *testutil.DNSPolicyBuilder + var gateway *gatewayv1beta1.Gateway + var dnsPolicy *v1alpha1.DNSPolicy + var lbHash, recordName, wildcardRecordName string + + BeforeAll(func() { + gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") + Expect(k8sClient.Create(ctx, gatewayClass)).To(BeNil()) + Eventually(func() error { // gateway class exists + return k8sClient.Get(ctx, client.ObjectKey{Name: gatewayClass.Name}, gatewayClass) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }) + + AfterAll(func() { + err := k8sClient.Delete(ctx, gatewayClass) + Expect(err).ToNot(HaveOccurred()) + }) + + BeforeEach(func() { + CreateNamespace(&testNamespace) + + managedZone = testutil.NewManagedZoneBuilder("mz-example-com", testNamespace, "example.com").ManagedZone + Expect(k8sClient.Create(ctx, managedZone)).To(BeNil()) + Eventually(func() error { // managed zone exists + return k8sClient.Get(ctx, client.ObjectKey{Name: managedZone.Name, Namespace: managedZone.Namespace}, managedZone) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + + gateway = testutil.NewGatewayBuilder(TestGatewayName, gatewayClass.Name, testNamespace). + WithHTTPListener(TestListenerNameOne, TestHostOne). + WithHTTPListener(TestListenerNameWildcard, TestHostWildcard). + Gateway + Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) + Eventually(func() error { //gateway exists + return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + //Set multi cluster gateway status + Eventually(func() error { + if err := k8sClient.Create(ctx, &v1.ManagedCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestClusterNameOne, + }, + }); err != nil && !k8serrors.IsAlreadyExists(err) { + return err + } + if err := k8sClient.Create(ctx, &v1.ManagedCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestClusterNameTwo, + }, + }); err != nil && !k8serrors.IsAlreadyExists(err) { + return err + } + gateway.Status.Addresses = []gatewayv1beta1.GatewayAddress{ + { + Type: testutil.Pointer(mgcgateway.MultiClusterIPAddressType), + Value: TestClusterNameOne + "/" + TestIPAddressOne, + }, + { + Type: testutil.Pointer(mgcgateway.MultiClusterIPAddressType), + Value: TestClusterNameTwo + "/" + TestIPAddressTwo, + }, + } + gateway.Status.Listeners = []gatewayv1beta1.ListenerStatus{ + { + Name: TestClusterNameOne + "." + TestListenerNameOne, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + { + Name: TestClusterNameTwo + "." + TestListenerNameOne, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + { + Name: TestClusterNameOne + "." + TestListenerNameWildcard, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + { + Name: TestClusterNameTwo + "." + TestListenerNameWildcard, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + } + return k8sClient.Status().Update(ctx, gateway) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + + dnsPolicyBuilder = testutil.NewDNSPolicyBuilder("test-dns-policy", testNamespace) + dnsPolicyBuilder.WithTargetGateway(TestGatewayName) + + lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) + recordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameOne) + wildcardRecordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameWildcard) + }) + + AfterEach(func() { + if gateway != nil { + err := k8sClient.Delete(ctx, gateway) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } + + if dnsPolicy != nil { + err := k8sClient.Delete(ctx, dnsPolicy) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + + } + if managedZone != nil { + err := k8sClient.Delete(ctx, managedZone) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } + }) + + Context("multi cluster gateway status", func() { + + Context("loadbalanced routing strategy", func() { + + BeforeEach(func() { + dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.LoadBalancedRoutingStrategy) + }) + + Context("with health checks", func() { + var unhealthy bool + + BeforeEach(func() { + dnsPolicyBuilder. + WithLoadBalancingWeightedFor(120, nil). + WithHealthCheckFor("/", nil, v1alpha1.HttpProtocol, testutil.Pointer(4)) + dnsPolicy = dnsPolicyBuilder.DNSPolicy + Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) + Eventually(func() error { //dns policy exists + return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }) + + It("should create dns records", func() { + Eventually(func(g Gomega, ctx context.Context) { + recordList := &v1alpha1.DNSRecordList{} + err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(recordList.Items).To(HaveLen(2)) + g.Expect(recordList.Items).To( + ContainElements( + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", recordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": HaveLen(6), + }), + }), + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", wildcardRecordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": HaveLen(6), + }), + }), + )) + }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) + }) + + It("should have probes that are healthy", func() { + probeList := &v1alpha1.DNSHealthCheckProbeList{} + Eventually(func() error { + Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) + if len(probeList.Items) != 2 { + return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Expect(len(probeList.Items)).To(Equal(2)) + }) + + Context("all unhealthy probes", func() { + It("should publish all dns records endpoints", func() { + + expectedEndpoints := []*v1alpha1.Endpoint{ + { + DNSName: "2w705o.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressTwo, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "s07c46.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressOne, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "2w705o.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "s07c46.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + Labels: nil, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "lb-" + lbHash + ".test.example.com", + Targets: []string{ + "default.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "default", + RecordTTL: 300, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "geo-code", + Value: "*", + }, + }, + }, + { + DNSName: "test.example.com", + Targets: []string{ + "lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "", + RecordTTL: 300, + }, + } + + probeList := &v1alpha1.DNSHealthCheckProbeList{} + Eventually(func() error { + Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) + if len(probeList.Items) != 2 { + return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + + for _, probe := range probeList.Items { + Eventually(func() error { + if probe.Name == fmt.Sprintf("%s-%s-%s", TestIPAddressTwo, TestGatewayName, TestHostOne) || + probe.Name == fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestHostOne) { + getProbe := &v1alpha1.DNSHealthCheckProbe{} + if err := k8sClient.Get(ctx, client.ObjectKey{Name: probe.Name, Namespace: probe.Namespace}, getProbe); err != nil { + return err + } + patch := client.MergeFrom(getProbe.DeepCopy()) + unhealthy = false + getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ + LastCheckedAt: metav1.NewTime(time.Now()), + ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, + Healthy: &unhealthy, + } + if err := k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { + return err + } + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + } + createdDNSRecord := &v1alpha1.DNSRecord{} + Eventually(func() error { + + err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) + if err != nil && k8serrors.IsNotFound(err) { + return err + } + if len(createdDNSRecord.Spec.Endpoints) != len(expectedEndpoints) { + return fmt.Errorf("expected %v endpoints in DNSRecord, got %v", len(expectedEndpoints), len(createdDNSRecord.Spec.Endpoints)) + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) + Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) + Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) + + }) + }) + Context("some unhealthy probes", func() { + It("should publish expected endpoints", func() { + + expectedEndpoints := []*v1alpha1.Endpoint{ + { + DNSName: "2w705o.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressTwo, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "s07c46.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressOne, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "2w705o.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "s07c46.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + Labels: nil, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "lb-" + lbHash + ".test.example.com", + Targets: []string{ + "default.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "default", + RecordTTL: 300, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "geo-code", + Value: "*", + }, + }, + }, + { + DNSName: "test.example.com", + Targets: []string{ + "lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "", + RecordTTL: 300, + }, + } + + probeList := &v1alpha1.DNSHealthCheckProbeList{} + Eventually(func() error { + Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) + if len(probeList.Items) != 2 { + return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + Expect(probeList.Items).To(HaveLen(2)) + + Eventually(func() error { + getProbe := &v1alpha1.DNSHealthCheckProbe{} + if err := k8sClient.Get(ctx, client.ObjectKey{Name: fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestListenerNameOne), Namespace: testNamespace}, getProbe); err != nil { + return err + } + patch := client.MergeFrom(getProbe.DeepCopy()) + unhealthy = false + getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ + LastCheckedAt: metav1.NewTime(time.Now()), + ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, + Healthy: &unhealthy, + } + if err := k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { + return err + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + + // after that verify that in time the endpoints are 5 in the dnsrecord + createdDNSRecord := &v1alpha1.DNSRecord{} + Eventually(func() error { + err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) + if err != nil && k8serrors.IsNotFound(err) { + return err + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) + Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) + Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) + }) + }) + Context("some unhealthy endpoints for other listener", func() { + It("should publish expected endpoints", func() { + + expectedEndpoints := []*v1alpha1.Endpoint{ + { + DNSName: "2w705o.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressTwo, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "s07c46.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressOne, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "2w705o.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "s07c46.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + Labels: nil, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "lb-" + lbHash + ".test.example.com", + Targets: []string{ + "default.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "default", + RecordTTL: 300, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "geo-code", + Value: "*", + }, + }, + }, + { + DNSName: "test.example.com", + Targets: []string{ + "lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "", + RecordTTL: 300, + }, + } + + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) + Expect(err).NotTo(HaveOccurred()) + Expect(gateway.Spec.Listeners).NotTo(BeNil()) + // add another listener, should result in 4 probes + typedHostname := gatewayv1beta1.Hostname(TestHostTwo) + otherListener := gatewayv1beta1.Listener{ + Name: gatewayv1beta1.SectionName(TestListenerNameTwo), + Hostname: &typedHostname, + Port: gatewayv1beta1.PortNumber(80), + Protocol: gatewayv1beta1.HTTPProtocolType, + } + + patch := client.MergeFrom(gateway.DeepCopy()) + gateway.Spec.Listeners = append(gateway.Spec.Listeners, otherListener) + Expect(k8sClient.Patch(ctx, gateway, patch)).To(BeNil()) + + probeList := &v1alpha1.DNSHealthCheckProbeList{} + Eventually(func() error { + Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) + if len(probeList.Items) != 4 { + return fmt.Errorf("expected %v probes, got %v", 4, len(probeList.Items)) + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + Expect(len(probeList.Items)).To(Equal(4)) + + // + Eventually(func() error { + getProbe := &v1alpha1.DNSHealthCheckProbe{} + if err = k8sClient.Get(ctx, client.ObjectKey{Name: fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestListenerNameTwo), Namespace: testNamespace}, getProbe); err != nil { + return err + } + patch := client.MergeFrom(getProbe.DeepCopy()) + unhealthy = false + getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ + LastCheckedAt: metav1.NewTime(time.Now()), + ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, + Healthy: &unhealthy, + } + if err = k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { + return err + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + + // after that verify that in time the endpoints are 5 in the dnsrecord + createdDNSRecord := &v1alpha1.DNSRecord{} + Eventually(func() error { + err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) + if err != nil && k8serrors.IsNotFound(err) { + return err + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) + Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) + Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) + }) + }) + }) + + }) + + }) + +}) diff --git a/test/policy_integration/dnspolicy_controller_multi_cluster_test.go b/test/policy_integration/dnspolicy_controller_multi_cluster_test.go new file mode 100644 index 00000000..35fb31a9 --- /dev/null +++ b/test/policy_integration/dnspolicy_controller_multi_cluster_test.go @@ -0,0 +1,923 @@ +//go:build integration + +package policy_integration + +import ( + "context" + "fmt" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gstruct" + v1 "open-cluster-management.io/api/cluster/v1" + + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + + "github.com/Kuadrant/multicluster-gateway-controller/pkg/apis/v1alpha1" + mgcgateway "github.com/Kuadrant/multicluster-gateway-controller/pkg/controllers/gateway" + "github.com/Kuadrant/multicluster-gateway-controller/pkg/dns" + testutil "github.com/Kuadrant/multicluster-gateway-controller/test/util" +) + +var _ = Describe("DNSPolicy Multi Cluster", Ordered, func() { + + var gatewayClass *gatewayv1beta1.GatewayClass + var managedZone *v1alpha1.ManagedZone + var testNamespace string + var dnsPolicyBuilder *testutil.DNSPolicyBuilder + var gateway *gatewayv1beta1.Gateway + var dnsPolicy *v1alpha1.DNSPolicy + var lbHash, recordName, wildcardRecordName string + + BeforeAll(func() { + gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") + Expect(k8sClient.Create(ctx, gatewayClass)).To(BeNil()) + Eventually(func() error { // gateway class exists + return k8sClient.Get(ctx, client.ObjectKey{Name: gatewayClass.Name}, gatewayClass) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }) + + AfterAll(func() { + err := k8sClient.Delete(ctx, gatewayClass) + Expect(err).ToNot(HaveOccurred()) + }) + + BeforeEach(func() { + CreateNamespace(&testNamespace) + + managedZone = testutil.NewManagedZoneBuilder("mz-example-com", testNamespace, "example.com").ManagedZone + Expect(k8sClient.Create(ctx, managedZone)).To(BeNil()) + Eventually(func() error { // managed zone exists + return k8sClient.Get(ctx, client.ObjectKey{Name: managedZone.Name, Namespace: managedZone.Namespace}, managedZone) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + + gateway = testutil.NewGatewayBuilder(TestGatewayName, gatewayClass.Name, testNamespace). + WithHTTPListener(TestListenerNameOne, TestHostOne). + WithHTTPListener(TestListenerNameWildcard, TestHostWildcard). + Gateway + Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) + Eventually(func() error { //gateway exists + return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + //Set multi cluster gateway status + Eventually(func() error { + if err := k8sClient.Create(ctx, &v1.ManagedCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestClusterNameOne, + }, + }); err != nil && !k8serrors.IsAlreadyExists(err) { + return err + } + if err := k8sClient.Create(ctx, &v1.ManagedCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestClusterNameTwo, + }, + }); err != nil && !k8serrors.IsAlreadyExists(err) { + return err + } + gateway.Status.Addresses = []gatewayv1beta1.GatewayAddress{ + { + Type: testutil.Pointer(mgcgateway.MultiClusterIPAddressType), + Value: TestClusterNameOne + "/" + TestIPAddressOne, + }, + { + Type: testutil.Pointer(mgcgateway.MultiClusterIPAddressType), + Value: TestClusterNameTwo + "/" + TestIPAddressTwo, + }, + } + gateway.Status.Listeners = []gatewayv1beta1.ListenerStatus{ + { + Name: TestClusterNameOne + "." + TestListenerNameOne, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + { + Name: TestClusterNameTwo + "." + TestListenerNameOne, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + { + Name: TestClusterNameOne + "." + TestListenerNameWildcard, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + { + Name: TestClusterNameTwo + "." + TestListenerNameWildcard, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + } + return k8sClient.Status().Update(ctx, gateway) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + + dnsPolicyBuilder = testutil.NewDNSPolicyBuilder("test-dns-policy", testNamespace) + dnsPolicyBuilder.WithTargetGateway(TestGatewayName) + + lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) + recordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameOne) + wildcardRecordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameWildcard) + }) + + AfterEach(func() { + if gateway != nil { + err := k8sClient.Delete(ctx, gateway) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } + + if dnsPolicy != nil { + err := k8sClient.Delete(ctx, dnsPolicy) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + + } + if managedZone != nil { + err := k8sClient.Delete(ctx, managedZone) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } + }) + + Context("simple routing strategy", func() { + + BeforeEach(func() { + dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy) + dnsPolicy = dnsPolicyBuilder.DNSPolicy + Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) + Eventually(func() error { //dns policy exists + return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }) + + It("should create dns records", func() { + Eventually(func(g Gomega, ctx context.Context) { + recordList := &v1alpha1.DNSRecordList{} + err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(recordList.Items).To(HaveLen(2)) + g.Expect(recordList.Items).To( + ContainElements( + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", recordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ConsistOf( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostOne), + "Targets": ContainElements(TestIPAddressOne, TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + ), + }), + }), + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", wildcardRecordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ConsistOf( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostWildcard), + "Targets": ContainElements(TestIPAddressOne, TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + ), + }), + }), + )) + }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) + }) + + }) + + Context("loadbalanced routing strategy", func() { + + BeforeEach(func() { + dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.LoadBalancedRoutingStrategy) + }) + + Context("weighted", func() { + + BeforeEach(func() { + dnsPolicyBuilder.WithLoadBalancingWeightedFor(120, nil) + dnsPolicy = dnsPolicyBuilder.DNSPolicy + Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) + Eventually(func() error { //dns policy exists + return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }) + + It("should create dns records", func() { + Eventually(func(g Gomega, ctx context.Context) { + recordList := &v1alpha1.DNSRecordList{} + err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(recordList.Items).To(HaveLen(2)) + g.Expect(recordList.Items).To( + ContainElements( + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", recordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ConsistOf( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("2w705o.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf(TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("default.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf("2w705o.lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("2w705o.lb-" + lbHash + ".test.example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("default.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf("s07c46.lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("s07c46.lb-" + lbHash + ".test.example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("s07c46.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf(TestIPAddressOne), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf("default.lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("default"), + "RecordTTL": Equal(v1alpha1.TTL(300)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostOne), + "Targets": ConsistOf("lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(300)), + })), + ), + }), + }), + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", wildcardRecordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ConsistOf( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("2w705o.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf(TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("default.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf("2w705o.lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("2w705o.lb-" + lbHash + ".example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("default.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf("s07c46.lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("s07c46.lb-" + lbHash + ".example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("s07c46.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf(TestIPAddressOne), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("lb-" + lbHash + ".example.com"), + "Targets": ConsistOf("default.lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("default"), + "RecordTTL": Equal(v1alpha1.TTL(300)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostWildcard), + "Targets": ConsistOf("lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(300)), + })), + ), + }), + }), + )) + }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) + }) + + }) + + Context("geo+weighted", func() { + + BeforeEach(func() { + dnsPolicyBuilder. + WithLoadBalancingWeightedFor(120, nil). + WithLoadBalancingGeoFor("IE") + dnsPolicy = dnsPolicyBuilder.DNSPolicy + Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) + Eventually(func() error { //dns policy exists + if err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy); err != nil { + return err + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + }) + + It("should create dns records", func() { + Eventually(func(g Gomega, ctx context.Context) { + recordList := &v1alpha1.DNSRecordList{} + err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(recordList.Items).To(HaveLen(2)) + g.Expect(recordList.Items).To( + ContainElements( + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", recordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ConsistOf( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("2w705o.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf(TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("ie.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf("2w705o.lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("2w705o.lb-" + lbHash + ".test.example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("ie.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf("s07c46.lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("s07c46.lb-" + lbHash + ".test.example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("s07c46.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf(TestIPAddressOne), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf("ie.lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("IE"), + "RecordTTL": Equal(v1alpha1.TTL(300)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "IE"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf("ie.lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("default"), + "RecordTTL": Equal(v1alpha1.TTL(300)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostOne), + "Targets": ConsistOf("lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(300)), + })), + ), + }), + }), + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", wildcardRecordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ConsistOf( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("2w705o.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf(TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("ie.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf("2w705o.lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("2w705o.lb-" + lbHash + ".example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("ie.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf("s07c46.lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("s07c46.lb-" + lbHash + ".example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("s07c46.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf(TestIPAddressOne), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("lb-" + lbHash + ".example.com"), + "Targets": ConsistOf("ie.lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("IE"), + "RecordTTL": Equal(v1alpha1.TTL(300)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "IE"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("lb-" + lbHash + ".example.com"), + "Targets": ConsistOf("ie.lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("default"), + "RecordTTL": Equal(v1alpha1.TTL(300)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostWildcard), + "Targets": ConsistOf("lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(300)), + })), + ), + }), + }), + )) + }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) + }) + + }) + + Context("with health checks", func() { + var unhealthy bool + + BeforeEach(func() { + dnsPolicyBuilder. + WithLoadBalancingWeightedFor(120, nil). + WithHealthCheckFor("/", nil, v1alpha1.HttpProtocol, testutil.Pointer(4)) + dnsPolicy = dnsPolicyBuilder.DNSPolicy + Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) + Eventually(func() error { //dns policy exists + return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }) + + It("should create a dns record", func() { + createdDNSRecord := &v1alpha1.DNSRecord{} + Eventually(func() error { // DNS record exists + if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord); err != nil { + return err + } + if len(createdDNSRecord.Spec.Endpoints) != 6 { + return fmt.Errorf("expected %v endpoints in DNSRecord, got %v", 6, len(createdDNSRecord.Spec.Endpoints)) + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(6)) + }) + It("should have probes that are healthy", func() { + probeList := &v1alpha1.DNSHealthCheckProbeList{} + Eventually(func() error { + Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) + if len(probeList.Items) != 2 { + return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Expect(len(probeList.Items)).To(Equal(2)) + }) + + Context("all unhealthy probes", func() { + It("should publish all dns records endpoints", func() { + lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) + + expectedEndpoints := []*v1alpha1.Endpoint{ + { + DNSName: "2w705o.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressTwo, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "s07c46.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressOne, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "2w705o.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "s07c46.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + Labels: nil, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "lb-" + lbHash + ".test.example.com", + Targets: []string{ + "default.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "default", + RecordTTL: 300, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "geo-code", + Value: "*", + }, + }, + }, + { + DNSName: "test.example.com", + Targets: []string{ + "lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "", + RecordTTL: 300, + }, + } + + probeList := &v1alpha1.DNSHealthCheckProbeList{} + Eventually(func() error { + Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) + if len(probeList.Items) != 2 { + return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + + for _, probe := range probeList.Items { + Eventually(func() error { + if probe.Name == fmt.Sprintf("%s-%s-%s", TestIPAddressTwo, TestGatewayName, TestHostOne) || + probe.Name == fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestHostOne) { + getProbe := &v1alpha1.DNSHealthCheckProbe{} + if err := k8sClient.Get(ctx, client.ObjectKey{Name: probe.Name, Namespace: probe.Namespace}, getProbe); err != nil { + return err + } + patch := client.MergeFrom(getProbe.DeepCopy()) + unhealthy = false + getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ + LastCheckedAt: metav1.NewTime(time.Now()), + ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, + Healthy: &unhealthy, + } + if err := k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { + return err + } + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + } + createdDNSRecord := &v1alpha1.DNSRecord{} + Eventually(func() error { + + err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) + if err != nil && k8serrors.IsNotFound(err) { + return err + } + if len(createdDNSRecord.Spec.Endpoints) != len(expectedEndpoints) { + return fmt.Errorf("expected %v endpoints in DNSRecord, got %v", len(expectedEndpoints), len(createdDNSRecord.Spec.Endpoints)) + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) + Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) + Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) + + }) + }) + Context("some unhealthy probes", func() { + It("should publish expected endpoints", func() { + lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) + + expectedEndpoints := []*v1alpha1.Endpoint{ + { + DNSName: "2w705o.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressTwo, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "s07c46.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressOne, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "2w705o.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "s07c46.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + Labels: nil, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "lb-" + lbHash + ".test.example.com", + Targets: []string{ + "default.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "default", + RecordTTL: 300, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "geo-code", + Value: "*", + }, + }, + }, + { + DNSName: "test.example.com", + Targets: []string{ + "lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "", + RecordTTL: 300, + }, + } + + probeList := &v1alpha1.DNSHealthCheckProbeList{} + Eventually(func() error { + Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) + if len(probeList.Items) != 2 { + return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + Expect(probeList.Items).To(HaveLen(2)) + + Eventually(func() error { + getProbe := &v1alpha1.DNSHealthCheckProbe{} + if err := k8sClient.Get(ctx, client.ObjectKey{Name: fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestListenerNameOne), Namespace: testNamespace}, getProbe); err != nil { + return err + } + patch := client.MergeFrom(getProbe.DeepCopy()) + unhealthy = false + getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ + LastCheckedAt: metav1.NewTime(time.Now()), + ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, + Healthy: &unhealthy, + } + if err := k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { + return err + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + + // after that verify that in time the endpoints are 5 in the dnsrecord + createdDNSRecord := &v1alpha1.DNSRecord{} + Eventually(func() error { + err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) + if err != nil && k8serrors.IsNotFound(err) { + return err + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) + Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) + Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) + }) + }) + Context("some unhealthy endpoints for other listener", func() { + It("should publish expected endpoints", func() { + lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) + + expectedEndpoints := []*v1alpha1.Endpoint{ + { + DNSName: "2w705o.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressTwo, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "s07c46.lb-" + lbHash + ".test.example.com", + Targets: []string{ + TestIPAddressOne, + }, + RecordType: "A", + SetIdentifier: "", + RecordTTL: 60, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "2w705o.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "default.lb-" + lbHash + ".test.example.com", + Targets: []string{ + "s07c46.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", + RecordTTL: 60, + Labels: nil, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "weight", + Value: "120", + }, + }, + }, + { + DNSName: "lb-" + lbHash + ".test.example.com", + Targets: []string{ + "default.lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "default", + RecordTTL: 300, + ProviderSpecific: v1alpha1.ProviderSpecific{ + { + Name: "geo-code", + Value: "*", + }, + }, + }, + { + DNSName: "test.example.com", + Targets: []string{ + "lb-" + lbHash + ".test.example.com", + }, + RecordType: "CNAME", + SetIdentifier: "", + RecordTTL: 300, + }, + } + + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) + Expect(err).NotTo(HaveOccurred()) + Expect(gateway.Spec.Listeners).NotTo(BeNil()) + // add another listener, should result in 4 probes + typedHostname := gatewayv1beta1.Hostname(TestHostTwo) + otherListener := gatewayv1beta1.Listener{ + Name: gatewayv1beta1.SectionName(TestListenerNameTwo), + Hostname: &typedHostname, + Port: gatewayv1beta1.PortNumber(80), + Protocol: gatewayv1beta1.HTTPProtocolType, + } + + patch := client.MergeFrom(gateway.DeepCopy()) + gateway.Spec.Listeners = append(gateway.Spec.Listeners, otherListener) + Expect(k8sClient.Patch(ctx, gateway, patch)).To(BeNil()) + + probeList := &v1alpha1.DNSHealthCheckProbeList{} + Eventually(func() error { + Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) + if len(probeList.Items) != 4 { + return fmt.Errorf("expected %v probes, got %v", 4, len(probeList.Items)) + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + Expect(len(probeList.Items)).To(Equal(4)) + + // + Eventually(func() error { + getProbe := &v1alpha1.DNSHealthCheckProbe{} + if err = k8sClient.Get(ctx, client.ObjectKey{Name: fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestListenerNameTwo), Namespace: testNamespace}, getProbe); err != nil { + return err + } + patch := client.MergeFrom(getProbe.DeepCopy()) + unhealthy = false + getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ + LastCheckedAt: metav1.NewTime(time.Now()), + ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, + Healthy: &unhealthy, + } + if err = k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { + return err + } + return nil + }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) + + // after that verify that in time the endpoints are 5 in the dnsrecord + createdDNSRecord := &v1alpha1.DNSRecord{} + Eventually(func() error { + err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) + if err != nil && k8serrors.IsNotFound(err) { + return err + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) + Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) + Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) + }) + }) + }) + + }) + +}) diff --git a/test/policy_integration/dnspolicy_controller_single_cluster_test.go b/test/policy_integration/dnspolicy_controller_single_cluster_test.go new file mode 100644 index 00000000..20bbd602 --- /dev/null +++ b/test/policy_integration/dnspolicy_controller_single_cluster_test.go @@ -0,0 +1,255 @@ +//go:build integration + +package policy_integration + +import ( + "context" + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gstruct" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + + "github.com/Kuadrant/multicluster-gateway-controller/pkg/apis/v1alpha1" + "github.com/Kuadrant/multicluster-gateway-controller/pkg/dns" + testutil "github.com/Kuadrant/multicluster-gateway-controller/test/util" +) + +var _ = Describe("DNSPolicy Single Cluster", Ordered, func() { + + var gatewayClass *gatewayv1beta1.GatewayClass + var managedZone *v1alpha1.ManagedZone + var testNamespace string + var dnsPolicyBuilder *testutil.DNSPolicyBuilder + var gateway *gatewayv1beta1.Gateway + var dnsPolicy *v1alpha1.DNSPolicy + var lbHash, recordName, wildcardRecordName string + + BeforeAll(func() { + gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") + Expect(k8sClient.Create(ctx, gatewayClass)).To(BeNil()) + Eventually(func() error { // gateway class exists + return k8sClient.Get(ctx, client.ObjectKey{Name: gatewayClass.Name}, gatewayClass) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }) + + AfterAll(func() { + err := k8sClient.Delete(ctx, gatewayClass) + Expect(err).ToNot(HaveOccurred()) + }) + + BeforeEach(func() { + CreateNamespace(&testNamespace) + + managedZone = testutil.NewManagedZoneBuilder("mz-example-com", testNamespace, "example.com").ManagedZone + Expect(k8sClient.Create(ctx, managedZone)).To(BeNil()) + Eventually(func() error { // managed zone exists + return k8sClient.Get(ctx, client.ObjectKey{Name: managedZone.Name, Namespace: managedZone.Namespace}, managedZone) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + + gateway = testutil.NewGatewayBuilder(TestGatewayName, gatewayClass.Name, testNamespace). + WithHTTPListener(TestListenerNameOne, TestHostOne). + WithHTTPListener(TestListenerNameWildcard, TestHostWildcard). + Gateway + Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) + Eventually(func() error { //gateway exists + return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + //Set single cluster gateway status + Eventually(func() error { + gateway.Status.Addresses = []gatewayv1beta1.GatewayAddress{ + { + Type: testutil.Pointer(gatewayv1beta1.IPAddressType), + Value: TestIPAddressOne, + }, + { + Type: testutil.Pointer(gatewayv1beta1.IPAddressType), + Value: TestIPAddressTwo, + }, + } + gateway.Status.Listeners = []gatewayv1beta1.ListenerStatus{ + { + Name: TestListenerNameOne, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + { + Name: TestListenerNameWildcard, + SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, + AttachedRoutes: 1, + Conditions: []metav1.Condition{}, + }, + } + return k8sClient.Status().Update(ctx, gateway) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + + dnsPolicyBuilder = testutil.NewDNSPolicyBuilder("test-dns-policy", testNamespace) + dnsPolicyBuilder.WithTargetGateway(TestGatewayName) + + lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) + recordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameOne) + wildcardRecordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameWildcard) + }) + + Context("simple routing strategy", func() { + + BeforeEach(func() { + dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy) + dnsPolicy = dnsPolicyBuilder.DNSPolicy + Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) + Eventually(func() error { //dns policy exists + return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }) + + It("should create dns records", func() { + Eventually(func(g Gomega, ctx context.Context) { + recordList := &v1alpha1.DNSRecordList{} + err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(recordList.Items).To(HaveLen(2)) + g.Expect(recordList.Items).To( + ContainElements( + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", recordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ConsistOf( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostOne), + "Targets": ContainElements(TestIPAddressOne, TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + ), + }), + }), + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", wildcardRecordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ConsistOf( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostWildcard), + "Targets": ContainElements(TestIPAddressOne, TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + ), + }), + }), + )) + }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) + }) + + }) + + Context("loadbalanced routing strategy", func() { + + BeforeEach(func() { + dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.LoadBalancedRoutingStrategy) + dnsPolicy = dnsPolicyBuilder.DNSPolicy + Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) + Eventually(func() error { //dns policy exists + return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) + }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }) + + It("should create dns records", func() { + Eventually(func(g Gomega, ctx context.Context) { + recordList := &v1alpha1.DNSRecordList{} + err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(recordList.Items).To(HaveLen(2)) + g.Expect(recordList.Items).To( + ContainElements( + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", recordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ConsistOf( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("19sc9b.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf(TestIPAddressOne, TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("default.lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf("19sc9b.lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("19sc9b.lb-" + lbHash + ".test.example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("lb-" + lbHash + ".test.example.com"), + "Targets": ConsistOf("default.lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("default"), + "RecordTTL": Equal(v1alpha1.TTL(300)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostOne), + "Targets": ConsistOf("lb-" + lbHash + ".test.example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(300)), + })), + ), + }), + }), + MatchFields(IgnoreExtras, Fields{ + "ObjectMeta": HaveField("Name", wildcardRecordName), + "Spec": MatchFields(IgnoreExtras, Fields{ + "ManagedZoneRef": HaveField("Name", "mz-example-com"), + "Endpoints": ContainElements( + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("19sc9b.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf(TestIPAddressOne, TestIPAddressTwo), + "RecordType": Equal("A"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(60)), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("default.lb-" + lbHash + ".example.com"), + "Targets": ConsistOf("19sc9b.lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("19sc9b.lb-" + lbHash + ".example.com"), + "RecordTTL": Equal(v1alpha1.TTL(60)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal("lb-" + lbHash + ".example.com"), + "Targets": ConsistOf("default.lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal("default"), + "RecordTTL": Equal(v1alpha1.TTL(300)), + "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), + })), + PointTo(MatchFields(IgnoreExtras, Fields{ + "DNSName": Equal(TestHostWildcard), + "Targets": ConsistOf("lb-" + lbHash + ".example.com"), + "RecordType": Equal("CNAME"), + "SetIdentifier": Equal(""), + "RecordTTL": Equal(v1alpha1.TTL(300)), + })), + ), + }), + }), + )) + }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) + }) + + }) + +}) diff --git a/test/policy_integration/dnspolicy_controller_test.go b/test/policy_integration/dnspolicy_controller_test.go index 17ff19fb..fca28768 100644 --- a/test/policy_integration/dnspolicy_controller_test.go +++ b/test/policy_integration/dnspolicy_controller_test.go @@ -3,7 +3,6 @@ package policy_integration import ( - "context" "encoding/json" "errors" "fmt" @@ -11,15 +10,12 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - . "github.com/onsi/gomega/gstruct" v1 "open-cluster-management.io/api/cluster/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" "github.com/Kuadrant/multicluster-gateway-controller/pkg/_internal/conditions" @@ -27,7 +23,6 @@ import ( "github.com/Kuadrant/multicluster-gateway-controller/pkg/apis/v1alpha1" . "github.com/Kuadrant/multicluster-gateway-controller/pkg/controllers/dnspolicy" mgcgateway "github.com/Kuadrant/multicluster-gateway-controller/pkg/controllers/gateway" - "github.com/Kuadrant/multicluster-gateway-controller/pkg/dns" testutil "github.com/Kuadrant/multicluster-gateway-controller/test/util" ) @@ -39,12 +34,9 @@ var _ = Describe("DNSPolicy", Ordered, func() { var dnsPolicyBuilder *testutil.DNSPolicyBuilder var gateway *gatewayv1beta1.Gateway var dnsPolicy *v1alpha1.DNSPolicy + var recordName, wildcardRecordName string BeforeAll(func() { - logger = zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)) - logger.WithName("dnspolicy_controller_test") - logf.SetLogger(logger) - gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") Expect(k8sClient.Create(ctx, gatewayClass)).To(BeNil()) Eventually(func() error { // gateway class exists @@ -67,21 +59,14 @@ var _ = Describe("DNSPolicy", Ordered, func() { err := k8sClient.Delete(ctx, gateway) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) } - if dnsPolicy != nil { err := k8sClient.Delete(ctx, dnsPolicy) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) } - gatewayList := &gatewayv1beta1.GatewayList{} - Expect(k8sClient.List(ctx, gatewayList)).To(BeNil()) - for _, gw := range gatewayList.Items { - k8sClient.Delete(ctx, &gw) - } - policyList := v1alpha1.DNSPolicyList{} - Expect(k8sClient.List(ctx, &policyList)).To(BeNil()) - for _, policy := range policyList.Items { - k8sClient.Delete(ctx, &policy) + if managedZone != nil { + err := k8sClient.Delete(ctx, managedZone) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) } }) @@ -189,7 +174,6 @@ var _ = Describe("DNSPolicy", Ordered, func() { BeforeEach(func() { gateway = testutil.NewGatewayBuilder(testGatewayName, gatewayClass.Name, testNamespace). WithHTTPListener(TestListenerNameOne, TestHostOne). - WithHTTPListener(TestListenerNameWildcard, TestHostWildcard). Gateway dnsPolicy = dnsPolicyBuilder. WithTargetGateway(testGatewayName). @@ -273,22 +257,25 @@ var _ = Describe("DNSPolicy", Ordered, func() { }) }) - Context("multi cluster gateway status", func() { - var lbHash, recordName, wildcardRecordName string + Context("valid target and valid gateway status", func() { BeforeEach(func() { gateway = testutil.NewGatewayBuilder(TestGatewayName, gatewayClass.Name, testNamespace). WithHTTPListener(TestListenerNameOne, TestHostOne). WithHTTPListener(TestListenerNameWildcard, TestHostWildcard). Gateway - dnsPolicyBuilder.WithTargetGateway(TestGatewayName) - lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) - recordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameOne) - wildcardRecordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameWildcard) - Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) - Eventually(func() error { //gateway exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + dnsPolicy = dnsPolicyBuilder.WithTargetGateway(TestGatewayName). + WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy). + //WithLoadBalancingWeightedFor(120, nil). + DNSPolicy + + Expect(k8sClient.Create(ctx, gateway)).To(Succeed()) + Expect(k8sClient.Create(ctx, dnsPolicy)).To(Succeed()) + + Eventually(func() error { //dns policy exists + return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Eventually(func() error { if err := k8sClient.Create(ctx, &v1.ManagedCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -304,6 +291,10 @@ var _ = Describe("DNSPolicy", Ordered, func() { }); err != nil && !k8serrors.IsAlreadyExists(err) { return err } + + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) + Expect(err).ShouldNot(HaveOccurred()) + gateway.Status.Addresses = []gatewayv1beta1.GatewayAddress{ { Type: testutil.Pointer(mgcgateway.MultiClusterIPAddressType), @@ -342,1173 +333,174 @@ var _ = Describe("DNSPolicy", Ordered, func() { } return k8sClient.Status().Update(ctx, gateway) }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) - - AfterEach(func() { - dnsRecordList := &v1alpha1.DNSRecordList{} - err := k8sClient.List(ctx, dnsRecordList) - Expect(err).ToNot(HaveOccurred()) - for _, record := range dnsRecordList.Items { - err := k8sClient.Delete(ctx, &record) - Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) - } + recordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameOne) + wildcardRecordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameWildcard) }) - Context("simple routing strategy", func() { - - BeforeEach(func() { - dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy) - dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) + It("should have correct status", func() { + Eventually(func() error { + if err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy); err != nil { + return err + } + if !meta.IsStatusConditionTrue(dnsPolicy.Status.Conditions, string(conditions.ConditionTypeReady)) { + return fmt.Errorf("expected status condition %s to be True", conditions.ConditionTypeReady) + } + if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), gateway); err != nil { + return err + } - It("should create dns records", func() { - Eventually(func(g Gomega, ctx context.Context) { - recordList := &v1alpha1.DNSRecordList{} - err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(recordList.Items).To(HaveLen(2)) - g.Expect(recordList.Items).To( - ContainElements( - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", recordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ConsistOf( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostOne), - "Targets": ContainElements(TestIPAddressOne, TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - ), - }), - }), - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", wildcardRecordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ConsistOf( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostWildcard), - "Targets": ContainElements(TestIPAddressOne, TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - ), - }), - }), - )) - }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) - }) + policyAffectedCond := meta.FindStatusCondition(gateway.Status.Conditions, string(DNSPolicyAffected)) + if policyAffectedCond == nil { + return fmt.Errorf("policy affected conditon expected but not found") + } + if policyAffectedCond.ObservedGeneration != gateway.Generation { + return fmt.Errorf("expected policy affected cond generation to be %d but got %d", gateway.Generation, policyAffectedCond.ObservedGeneration) + } + if !meta.IsStatusConditionTrue(gateway.Status.Conditions, string(DNSPolicyAffected)) { + return fmt.Errorf("expected gateway status condition %s to be True", DNSPolicyAffected) + } + return nil + }, time.Second*15, time.Second).Should(BeNil()) }) - Context("loadbalanced routing strategy", func() { - - BeforeEach(func() { - dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.LoadBalancedRoutingStrategy) - }) - - Context("weighted", func() { - - BeforeEach(func() { - dnsPolicyBuilder.WithLoadBalancingWeightedFor(120, nil) - dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) - - It("should create dns records", func() { - Eventually(func(g Gomega, ctx context.Context) { - recordList := &v1alpha1.DNSRecordList{} - err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(recordList.Items).To(HaveLen(2)) - g.Expect(recordList.Items).To( - ContainElements( - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", recordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ConsistOf( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("2w705o.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf(TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("default.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf("2w705o.lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("2w705o.lb-" + lbHash + ".test.example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("default.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf("s07c46.lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("s07c46.lb-" + lbHash + ".test.example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("s07c46.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf(TestIPAddressOne), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf("default.lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("default"), - "RecordTTL": Equal(v1alpha1.TTL(300)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostOne), - "Targets": ConsistOf("lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(300)), - })), - ), - }), - }), - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", wildcardRecordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ConsistOf( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("2w705o.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf(TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("default.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf("2w705o.lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("2w705o.lb-" + lbHash + ".example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("default.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf("s07c46.lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("s07c46.lb-" + lbHash + ".example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("s07c46.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf(TestIPAddressOne), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("lb-" + lbHash + ".example.com"), - "Targets": ConsistOf("default.lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("default"), - "RecordTTL": Equal(v1alpha1.TTL(300)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostWildcard), - "Targets": ConsistOf("lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(300)), - })), - ), - }), - }), - )) - }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) - }) - - It("should have correct status", func() { - Eventually(func() error { - if err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy); err != nil { - return err - } - if !meta.IsStatusConditionTrue(dnsPolicy.Status.Conditions, string(conditions.ConditionTypeReady)) { - return fmt.Errorf("expected status condition %s to be True", conditions.ConditionTypeReady) - } - if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), gateway); err != nil { - return err - } - - policyAffectedCond := meta.FindStatusCondition(gateway.Status.Conditions, string(DNSPolicyAffected)) - if policyAffectedCond == nil { - return fmt.Errorf("policy affected conditon expected but not found") - } - if policyAffectedCond.ObservedGeneration != gateway.Generation { - return fmt.Errorf("expected policy affected cond generation to be %d but got %d", gateway.Generation, policyAffectedCond.ObservedGeneration) - } - if !meta.IsStatusConditionTrue(gateway.Status.Conditions, string(DNSPolicyAffected)) { - return fmt.Errorf("expected gateway status condition %s to be True", DNSPolicyAffected) - } - - return nil - }, time.Second*15, time.Second).Should(BeNil()) - }) - - It("should set gateway back reference", func() { - existingGateway := &gatewayv1beta1.Gateway{} - policyBackRefValue := testNamespace + "/" + dnsPolicy.Name - refs, _ := json.Marshal([]client.ObjectKey{{Name: dnsPolicy.Name, Namespace: testNamespace}}) - policiesBackRefValue := string(refs) - - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPolicyBackRefAnnotation, policyBackRefValue)) - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) - }) - - It("should remove dns records when listener removed", func() { - //get the gateway and remove the listeners - - Eventually(func() error { - existingGateway := &gatewayv1beta1.Gateway{} - if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), existingGateway); err != nil { - return err - } - newListeners := []gatewayv1beta1.Listener{} - for _, existing := range existingGateway.Spec.Listeners { - if existing.Name == TestListenerNameWildcard { - newListeners = append(newListeners, existing) - } - } - - patch := client.MergeFrom(existingGateway.DeepCopy()) - existingGateway.Spec.Listeners = newListeners - rec := &v1alpha1.DNSRecord{} - if err := k8sClient.Patch(ctx, existingGateway, patch); err != nil { - return err - } - //dns record should be removed for non wildcard - if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, rec); err != nil && !k8serrors.IsNotFound(err) { - return err - } - return k8sClient.Get(ctx, client.ObjectKey{Name: wildcardRecordName, Namespace: testNamespace}, rec) - }, time.Second*10, time.Second).Should(BeNil()) - }) - - It("should remove gateway back reference on policy deletion", func() { - existingGateway := &gatewayv1beta1.Gateway{} - policyBackRefValue := testNamespace + "/" + dnsPolicy.Name - refs, _ := json.Marshal([]client.ObjectKey{{Name: dnsPolicy.Name, Namespace: testNamespace}}) - policiesBackRefValue := string(refs) - - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPolicyBackRefAnnotation, policyBackRefValue)) - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) - - //finalizer should exist - Eventually(func() bool { - existingDNSPolicy := &v1alpha1.DNSPolicy{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: testNamespace}, existingDNSPolicy) - // must exist - Expect(err).ToNot(HaveOccurred()) - return metadata.HasFinalizer(existingDNSPolicy, DNSPolicyFinalizer) - }, time.Second*5, time.Second).Should(BeTrue()) - - Expect(k8sClient.Delete(ctx, dnsPolicy)).To(BeNil()) - - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).ShouldNot(HaveKey(DNSPolicyBackRefAnnotation)) - - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).ShouldNot(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) - - Eventually(func() error { - // Check gateway back references - if err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway); err != nil { - return err - } - cond := meta.FindStatusCondition(existingGateway.Status.Conditions, string(DNSPolicyAffected)) - if cond != nil { - return fmt.Errorf("expected the condition %s to be gone", DNSPolicyAffected) - } - return nil - }, time.Second*5, time.Second).Should(BeNil()) - }) - - It("should remove dns record reference on policy deletion even if gateway is removed", func() { - createdDNSRecord := &v1alpha1.DNSRecord{} - Eventually(func() error { // DNS record exists - if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord); err != nil { - return err - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - - err := k8sClient.Delete(ctx, gateway) - Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) - - err = k8sClient.Delete(ctx, dnsPolicy) - Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) - - Eventually(func() error { // DNS record removed - if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord); err != nil { - if k8serrors.IsNotFound(err) { - return nil - } - return err - } - return errors.New("found dnsrecord when it should be deleted") - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - }) - - }) - - Context("geo+weighted", func() { - - BeforeEach(func() { - dnsPolicyBuilder. - WithLoadBalancingWeightedFor(120, nil). - WithLoadBalancingGeoFor("IE") - dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - if err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy); err != nil { - return err - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - }) - - It("should create dns records", func() { - Eventually(func(g Gomega, ctx context.Context) { - recordList := &v1alpha1.DNSRecordList{} - err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(recordList.Items).To(HaveLen(2)) - g.Expect(recordList.Items).To( - ContainElements( - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", recordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ConsistOf( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("2w705o.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf(TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("ie.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf("2w705o.lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("2w705o.lb-" + lbHash + ".test.example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("ie.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf("s07c46.lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("s07c46.lb-" + lbHash + ".test.example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("s07c46.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf(TestIPAddressOne), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf("ie.lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("IE"), - "RecordTTL": Equal(v1alpha1.TTL(300)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "IE"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf("ie.lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("default"), - "RecordTTL": Equal(v1alpha1.TTL(300)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostOne), - "Targets": ConsistOf("lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(300)), - })), - ), - }), - }), - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", wildcardRecordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ConsistOf( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("2w705o.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf(TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("ie.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf("2w705o.lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("2w705o.lb-" + lbHash + ".example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("ie.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf("s07c46.lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("s07c46.lb-" + lbHash + ".example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("s07c46.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf(TestIPAddressOne), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("lb-" + lbHash + ".example.com"), - "Targets": ConsistOf("ie.lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("IE"), - "RecordTTL": Equal(v1alpha1.TTL(300)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "IE"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("lb-" + lbHash + ".example.com"), - "Targets": ConsistOf("ie.lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("default"), - "RecordTTL": Equal(v1alpha1.TTL(300)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostWildcard), - "Targets": ConsistOf("lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(300)), - })), - ), - }), - }), - )) - }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) - }) - - }) - - Context("with health checks", func() { - var unhealthy bool - - BeforeEach(func() { - dnsPolicyBuilder. - WithLoadBalancingWeightedFor(120, nil). - WithHealthCheckFor("/", nil, v1alpha1.HttpProtocol, testutil.Pointer(4)) - dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) - - It("should create a dns record", func() { - createdDNSRecord := &v1alpha1.DNSRecord{} - Eventually(func() error { // DNS record exists - if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord); err != nil { - return err - } - if len(createdDNSRecord.Spec.Endpoints) != 6 { - return fmt.Errorf("expected %v endpoints in DNSRecord, got %v", 6, len(createdDNSRecord.Spec.Endpoints)) - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(6)) - }) - It("should have probes that are healthy", func() { - probeList := &v1alpha1.DNSHealthCheckProbeList{} - Eventually(func() error { - Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) - if len(probeList.Items) != 2 { - return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - Expect(len(probeList.Items)).To(Equal(2)) - }) - - Context("all unhealthy probes", func() { - It("should publish all dns records endpoints", func() { - lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) - - expectedEndpoints := []*v1alpha1.Endpoint{ - { - DNSName: "2w705o.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressTwo, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "s07c46.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressOne, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "2w705o.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "s07c46.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - Labels: nil, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "lb-" + lbHash + ".test.example.com", - Targets: []string{ - "default.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "default", - RecordTTL: 300, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "geo-code", - Value: "*", - }, - }, - }, - { - DNSName: "test.example.com", - Targets: []string{ - "lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "", - RecordTTL: 300, - }, - } - - probeList := &v1alpha1.DNSHealthCheckProbeList{} - Eventually(func() error { - Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) - if len(probeList.Items) != 2 { - return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - - for _, probe := range probeList.Items { - Eventually(func() error { - if probe.Name == fmt.Sprintf("%s-%s-%s", TestIPAddressTwo, TestGatewayName, TestHostOne) || - probe.Name == fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestHostOne) { - getProbe := &v1alpha1.DNSHealthCheckProbe{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: probe.Name, Namespace: probe.Namespace}, getProbe); err != nil { - return err - } - patch := client.MergeFrom(getProbe.DeepCopy()) - unhealthy = false - getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ - LastCheckedAt: metav1.NewTime(time.Now()), - ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, - Healthy: &unhealthy, - } - if err := k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { - return err - } - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - } - createdDNSRecord := &v1alpha1.DNSRecord{} - Eventually(func() error { - - err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) - if err != nil && k8serrors.IsNotFound(err) { - return err - } - if len(createdDNSRecord.Spec.Endpoints) != len(expectedEndpoints) { - return fmt.Errorf("expected %v endpoints in DNSRecord, got %v", len(expectedEndpoints), len(createdDNSRecord.Spec.Endpoints)) - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) - Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) - Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) - - }) - }) - Context("some unhealthy probes", func() { - It("should publish expected endpoints", func() { - lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) - - expectedEndpoints := []*v1alpha1.Endpoint{ - { - DNSName: "2w705o.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressTwo, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "s07c46.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressOne, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "2w705o.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "s07c46.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - Labels: nil, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "lb-" + lbHash + ".test.example.com", - Targets: []string{ - "default.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "default", - RecordTTL: 300, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "geo-code", - Value: "*", - }, - }, - }, - { - DNSName: "test.example.com", - Targets: []string{ - "lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "", - RecordTTL: 300, - }, - } - - probeList := &v1alpha1.DNSHealthCheckProbeList{} - Eventually(func() error { - Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) - if len(probeList.Items) != 2 { - return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - Expect(probeList.Items).To(HaveLen(2)) - - Eventually(func() error { - getProbe := &v1alpha1.DNSHealthCheckProbe{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestListenerNameOne), Namespace: testNamespace}, getProbe); err != nil { - return err - } - patch := client.MergeFrom(getProbe.DeepCopy()) - unhealthy = false - getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ - LastCheckedAt: metav1.NewTime(time.Now()), - ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, - Healthy: &unhealthy, - } - if err := k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { - return err - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - - // after that verify that in time the endpoints are 5 in the dnsrecord - createdDNSRecord := &v1alpha1.DNSRecord{} - Eventually(func() error { - err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) - if err != nil && k8serrors.IsNotFound(err) { - return err - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) - Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) - Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) - }) - }) - Context("some unhealthy endpoints for other listener", func() { - It("should publish expected endpoints", func() { - lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) - - expectedEndpoints := []*v1alpha1.Endpoint{ - { - DNSName: "2w705o.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressTwo, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "s07c46.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressOne, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "2w705o.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "s07c46.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - Labels: nil, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "lb-" + lbHash + ".test.example.com", - Targets: []string{ - "default.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "default", - RecordTTL: 300, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "geo-code", - Value: "*", - }, - }, - }, - { - DNSName: "test.example.com", - Targets: []string{ - "lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "", - RecordTTL: 300, - }, - } - - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) - Expect(err).NotTo(HaveOccurred()) - Expect(gateway.Spec.Listeners).NotTo(BeNil()) - // add another listener, should result in 4 probes - typedHostname := gatewayv1beta1.Hostname(TestHostTwo) - otherListener := gatewayv1beta1.Listener{ - Name: gatewayv1beta1.SectionName(TestListenerNameTwo), - Hostname: &typedHostname, - Port: gatewayv1beta1.PortNumber(80), - Protocol: gatewayv1beta1.HTTPProtocolType, - } - - patch := client.MergeFrom(gateway.DeepCopy()) - gateway.Spec.Listeners = append(gateway.Spec.Listeners, otherListener) - Expect(k8sClient.Patch(ctx, gateway, patch)).To(BeNil()) - - probeList := &v1alpha1.DNSHealthCheckProbeList{} - Eventually(func() error { - Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) - if len(probeList.Items) != 4 { - return fmt.Errorf("expected %v probes, got %v", 4, len(probeList.Items)) - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - Expect(len(probeList.Items)).To(Equal(4)) - - // - Eventually(func() error { - getProbe := &v1alpha1.DNSHealthCheckProbe{} - if err = k8sClient.Get(ctx, client.ObjectKey{Name: fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestListenerNameTwo), Namespace: testNamespace}, getProbe); err != nil { - return err - } - patch := client.MergeFrom(getProbe.DeepCopy()) - unhealthy = false - getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ - LastCheckedAt: metav1.NewTime(time.Now()), - ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, - Healthy: &unhealthy, - } - if err = k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { - return err - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - - // after that verify that in time the endpoints are 5 in the dnsrecord - createdDNSRecord := &v1alpha1.DNSRecord{} - Eventually(func() error { - err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) - if err != nil && k8serrors.IsNotFound(err) { - return err - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) - Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) - Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) - }) - }) - }) + It("should set gateway back reference", func() { + existingGateway := &gatewayv1beta1.Gateway{} + policyBackRefValue := testNamespace + "/" + dnsPolicy.Name + refs, _ := json.Marshal([]client.ObjectKey{{Name: dnsPolicy.Name, Namespace: testNamespace}}) + policiesBackRefValue := string(refs) + Eventually(func() map[string]string { + // Check gateway back references + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) + // must exist + Expect(err).ToNot(HaveOccurred()) + return existingGateway.GetAnnotations() + }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPolicyBackRefAnnotation, policyBackRefValue)) + Eventually(func() map[string]string { + // Check gateway back references + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) + // must exist + Expect(err).ToNot(HaveOccurred()) + return existingGateway.GetAnnotations() + }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) }) - }) - - Context("single cluster gateway status", func() { - var lbHash, recordName, wildcardRecordName string + It("should remove dns records when listener removed", func() { + //get the gateway and remove the listeners - BeforeEach(func() { - gateway = testutil.NewGatewayBuilder(TestGatewayName, gatewayClass.Name, testNamespace). - WithHTTPListener(TestListenerNameOne, TestHostOne). - WithHTTPListener(TestListenerNameWildcard, TestHostWildcard). - Gateway - dnsPolicyBuilder.WithTargetGateway(TestGatewayName) - lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) - recordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameOne) - wildcardRecordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameWildcard) - Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) - Eventually(func() error { //gateway exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) Eventually(func() error { - gateway.Status.Addresses = []gatewayv1beta1.GatewayAddress{ - { - Type: testutil.Pointer(gatewayv1beta1.IPAddressType), - Value: TestIPAddressOne, - }, - { - Type: testutil.Pointer(gatewayv1beta1.IPAddressType), - Value: TestIPAddressTwo, - }, + existingGateway := &gatewayv1beta1.Gateway{} + if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), existingGateway); err != nil { + return err } - gateway.Status.Listeners = []gatewayv1beta1.ListenerStatus{ - { - Name: TestListenerNameOne, - SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, - AttachedRoutes: 1, - Conditions: []metav1.Condition{}, - }, - { - Name: TestListenerNameWildcard, - SupportedKinds: []gatewayv1beta1.RouteGroupKind{}, - AttachedRoutes: 1, - Conditions: []metav1.Condition{}, - }, + newListeners := []gatewayv1beta1.Listener{} + for _, existing := range existingGateway.Spec.Listeners { + if existing.Name == TestListenerNameWildcard { + newListeners = append(newListeners, existing) + } } - return k8sClient.Status().Update(ctx, gateway) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + + patch := client.MergeFrom(existingGateway.DeepCopy()) + existingGateway.Spec.Listeners = newListeners + rec := &v1alpha1.DNSRecord{} + if err := k8sClient.Patch(ctx, existingGateway, patch); err != nil { + return err + } + //dns record should be removed for non wildcard + if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, rec); err != nil && !k8serrors.IsNotFound(err) { + return err + } + return k8sClient.Get(ctx, client.ObjectKey{Name: wildcardRecordName, Namespace: testNamespace}, rec) + }, time.Second*10, time.Second).Should(BeNil()) }) - AfterEach(func() { - dnsRecordList := &v1alpha1.DNSRecordList{} - err := k8sClient.List(ctx, dnsRecordList) - Expect(err).ToNot(HaveOccurred()) + It("should remove gateway back reference on policy deletion", func() { + existingGateway := &gatewayv1beta1.Gateway{} + policyBackRefValue := testNamespace + "/" + dnsPolicy.Name + refs, _ := json.Marshal([]client.ObjectKey{{Name: dnsPolicy.Name, Namespace: testNamespace}}) + policiesBackRefValue := string(refs) - for _, record := range dnsRecordList.Items { - err := k8sClient.Delete(ctx, &record) - Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) - } - }) + Eventually(func() map[string]string { + // Check gateway back references + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) + // must exist + Expect(err).ToNot(HaveOccurred()) + return existingGateway.GetAnnotations() + }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPolicyBackRefAnnotation, policyBackRefValue)) + Eventually(func() map[string]string { + // Check gateway back references + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) + // must exist + Expect(err).ToNot(HaveOccurred()) + return existingGateway.GetAnnotations() + }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) + + //finalizer should exist + Eventually(func() bool { + existingDNSPolicy := &v1alpha1.DNSPolicy{} + err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: testNamespace}, existingDNSPolicy) + // must exist + Expect(err).ToNot(HaveOccurred()) + return metadata.HasFinalizer(existingDNSPolicy, DNSPolicyFinalizer) + }, time.Second*5, time.Second).Should(BeTrue()) - Context("simple routing strategy", func() { + Expect(k8sClient.Delete(ctx, dnsPolicy)).To(BeNil()) - BeforeEach(func() { - dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy) - dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) + Eventually(func() map[string]string { + // Check gateway back references + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, existingGateway) + // must exist + Expect(err).ToNot(HaveOccurred()) + return existingGateway.GetAnnotations() + }, time.Second*5, time.Second).ShouldNot(HaveKey(DNSPolicyBackRefAnnotation)) - It("should create dns records", func() { - Eventually(func(g Gomega, ctx context.Context) { - recordList := &v1alpha1.DNSRecordList{} - err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(recordList.Items).To(HaveLen(2)) - g.Expect(recordList.Items).To( - ContainElements( - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", recordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ConsistOf( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostOne), - "Targets": ContainElements(TestIPAddressOne, TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - ), - }), - }), - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", wildcardRecordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ConsistOf( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostWildcard), - "Targets": ContainElements(TestIPAddressOne, TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - ), - }), - }), - )) - }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) - }) + Eventually(func() map[string]string { + // Check gateway back references + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) + // must exist + Expect(err).ToNot(HaveOccurred()) + return existingGateway.GetAnnotations() + }, time.Second*5, time.Second).ShouldNot(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) + Eventually(func() error { + // Check gateway back references + if err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway); err != nil { + return err + } + cond := meta.FindStatusCondition(existingGateway.Status.Conditions, string(DNSPolicyAffected)) + if cond != nil { + return fmt.Errorf("expected the condition %s to be gone", DNSPolicyAffected) + } + return nil + }, time.Second*5, time.Second).Should(BeNil()) }) - Context("loadbalanced routing strategy", func() { + It("should remove dns record reference on policy deletion even if gateway is removed", func() { + createdDNSRecord := &v1alpha1.DNSRecord{} + Eventually(func() error { // DNS record exists + if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord); err != nil { + return err + } + return nil + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - BeforeEach(func() { - dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.LoadBalancedRoutingStrategy) - dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) + err := k8sClient.Delete(ctx, gateway) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) - It("should create dns records", func() { - Eventually(func(g Gomega, ctx context.Context) { - recordList := &v1alpha1.DNSRecordList{} - err := k8sClient.List(ctx, recordList, &client.ListOptions{Namespace: testNamespace}) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(recordList.Items).To(HaveLen(2)) - g.Expect(recordList.Items).To( - ContainElements( - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", recordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ConsistOf( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("19sc9b.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf(TestIPAddressOne, TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("default.lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf("19sc9b.lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("19sc9b.lb-" + lbHash + ".test.example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("lb-" + lbHash + ".test.example.com"), - "Targets": ConsistOf("default.lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("default"), - "RecordTTL": Equal(v1alpha1.TTL(300)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostOne), - "Targets": ConsistOf("lb-" + lbHash + ".test.example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(300)), - })), - ), - }), - }), - MatchFields(IgnoreExtras, Fields{ - "ObjectMeta": HaveField("Name", wildcardRecordName), - "Spec": MatchFields(IgnoreExtras, Fields{ - "ManagedZoneRef": HaveField("Name", "mz-example-com"), - "Endpoints": ContainElements( - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("19sc9b.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf(TestIPAddressOne, TestIPAddressTwo), - "RecordType": Equal("A"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(60)), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("default.lb-" + lbHash + ".example.com"), - "Targets": ConsistOf("19sc9b.lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("19sc9b.lb-" + lbHash + ".example.com"), - "RecordTTL": Equal(v1alpha1.TTL(60)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "weight", Value: "120"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal("lb-" + lbHash + ".example.com"), - "Targets": ConsistOf("default.lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal("default"), - "RecordTTL": Equal(v1alpha1.TTL(300)), - "ProviderSpecific": Equal(v1alpha1.ProviderSpecific{{Name: "geo-code", Value: "*"}}), - })), - PointTo(MatchFields(IgnoreExtras, Fields{ - "DNSName": Equal(TestHostWildcard), - "Targets": ConsistOf("lb-" + lbHash + ".example.com"), - "RecordType": Equal("CNAME"), - "SetIdentifier": Equal(""), - "RecordTTL": Equal(v1alpha1.TTL(300)), - })), - ), - }), - }), - )) - }, TestTimeoutMedium, TestRetryIntervalMedium, ctx).Should(Succeed()) - }) + err = k8sClient.Delete(ctx, dnsPolicy) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + Eventually(func() error { // DNS record removed + if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord); err != nil { + if k8serrors.IsNotFound(err) { + return nil + } + return err + } + return errors.New("found dnsrecord when it should be deleted") + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) }) }) diff --git a/test/policy_integration/suite_test.go b/test/policy_integration/suite_test.go index 7752aa43..80c9effd 100644 --- a/test/policy_integration/suite_test.go +++ b/test/policy_integration/suite_test.go @@ -71,7 +71,7 @@ func testClient() client.Client { return k8sClient } func TestAPIs(t *testing.T) { RegisterFailHandler(Fail) - RunSpecs(t, "Controller Suite") + RunSpecs(t, "Policy Controller Suite") } var _ = BeforeSuite(func() { diff --git a/test/policy_integration/tlspolicy_controller_test.go b/test/policy_integration/tlspolicy_controller_test.go index f593ec60..8d279a35 100644 --- a/test/policy_integration/tlspolicy_controller_test.go +++ b/test/policy_integration/tlspolicy_controller_test.go @@ -15,8 +15,6 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" "github.com/Kuadrant/multicluster-gateway-controller/pkg/_internal/conditions" @@ -33,10 +31,6 @@ var _ = Describe("TLSPolicy", Ordered, func() { var issuer *certmanv1.Issuer BeforeAll(func() { - logger = zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)) - logger.WithName("tlspolicy_controller_test") - logf.SetLogger(logger) - gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") Expect(k8sClient.Create(ctx, gatewayClass)).To(BeNil()) Eventually(func() error { // gateway class exists From c6d6dace2b9fed61760d350165e3f5dfde5512a4 Mon Sep 17 00:00:00 2001 From: Michael Nairn Date: Tue, 14 Nov 2023 00:23:45 +0000 Subject: [PATCH 2/2] Make better use of gomega matchers Remove BeforeAll in favour of just using BeforeEach all setup. --- ...dnspolicy_controller_health_checks_test.go | 38 +- ...dnspolicy_controller_multi_cluster_test.go | 484 +----------------- ...nspolicy_controller_single_cluster_test.go | 61 ++- .../dnspolicy_controller_test.go | 371 +++++--------- 4 files changed, 186 insertions(+), 768 deletions(-) diff --git a/test/policy_integration/dnspolicy_controller_health_checks_test.go b/test/policy_integration/dnspolicy_controller_health_checks_test.go index 103e2747..d88b84fa 100644 --- a/test/policy_integration/dnspolicy_controller_health_checks_test.go +++ b/test/policy_integration/dnspolicy_controller_health_checks_test.go @@ -23,7 +23,7 @@ import ( testutil "github.com/Kuadrant/multicluster-gateway-controller/test/util" ) -var _ = Describe("DNSPolicy Health Checks", Ordered, func() { +var _ = Describe("DNSPolicy Health Checks", func() { var gatewayClass *gatewayv1beta1.GatewayClass var managedZone *v1alpha1.ManagedZone @@ -33,36 +33,21 @@ var _ = Describe("DNSPolicy Health Checks", Ordered, func() { var dnsPolicy *v1alpha1.DNSPolicy var lbHash, recordName, wildcardRecordName string - BeforeAll(func() { - gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") - Expect(k8sClient.Create(ctx, gatewayClass)).To(BeNil()) - Eventually(func() error { // gateway class exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gatewayClass.Name}, gatewayClass) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) - - AfterAll(func() { - err := k8sClient.Delete(ctx, gatewayClass) - Expect(err).ToNot(HaveOccurred()) - }) - BeforeEach(func() { CreateNamespace(&testNamespace) + gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") + Expect(k8sClient.Create(ctx, gatewayClass)).To(Succeed()) + managedZone = testutil.NewManagedZoneBuilder("mz-example-com", testNamespace, "example.com").ManagedZone - Expect(k8sClient.Create(ctx, managedZone)).To(BeNil()) - Eventually(func() error { // managed zone exists - return k8sClient.Get(ctx, client.ObjectKey{Name: managedZone.Name, Namespace: managedZone.Namespace}, managedZone) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, managedZone)).To(Succeed()) gateway = testutil.NewGatewayBuilder(TestGatewayName, gatewayClass.Name, testNamespace). WithHTTPListener(TestListenerNameOne, TestHostOne). WithHTTPListener(TestListenerNameWildcard, TestHostWildcard). Gateway - Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) - Eventually(func() error { //gateway exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, gateway)).To(Succeed()) + //Set multi cluster gateway status Eventually(func() error { if err := k8sClient.Create(ctx, &v1.ManagedCluster{ @@ -131,7 +116,6 @@ var _ = Describe("DNSPolicy Health Checks", Ordered, func() { err := k8sClient.Delete(ctx, gateway) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) } - if dnsPolicy != nil { err := k8sClient.Delete(ctx, dnsPolicy) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) @@ -141,6 +125,10 @@ var _ = Describe("DNSPolicy Health Checks", Ordered, func() { err := k8sClient.Delete(ctx, managedZone) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) } + if gatewayClass != nil { + err := k8sClient.Delete(ctx, gatewayClass) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } }) Context("multi cluster gateway status", func() { @@ -327,8 +315,6 @@ var _ = Describe("DNSPolicy Health Checks", Ordered, func() { }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) - Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) - }) }) Context("some unhealthy probes", func() { @@ -449,7 +435,6 @@ var _ = Describe("DNSPolicy Health Checks", Ordered, func() { }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) - Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) }) }) Context("some unhealthy endpoints for other listener", func() { @@ -587,7 +572,6 @@ var _ = Describe("DNSPolicy Health Checks", Ordered, func() { }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) - Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) }) }) }) diff --git a/test/policy_integration/dnspolicy_controller_multi_cluster_test.go b/test/policy_integration/dnspolicy_controller_multi_cluster_test.go index 35fb31a9..dde6661d 100644 --- a/test/policy_integration/dnspolicy_controller_multi_cluster_test.go +++ b/test/policy_integration/dnspolicy_controller_multi_cluster_test.go @@ -5,7 +5,6 @@ package policy_integration import ( "context" "fmt" - "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -23,7 +22,7 @@ import ( testutil "github.com/Kuadrant/multicluster-gateway-controller/test/util" ) -var _ = Describe("DNSPolicy Multi Cluster", Ordered, func() { +var _ = Describe("DNSPolicy Multi Cluster", func() { var gatewayClass *gatewayv1beta1.GatewayClass var managedZone *v1alpha1.ManagedZone @@ -33,36 +32,21 @@ var _ = Describe("DNSPolicy Multi Cluster", Ordered, func() { var dnsPolicy *v1alpha1.DNSPolicy var lbHash, recordName, wildcardRecordName string - BeforeAll(func() { - gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") - Expect(k8sClient.Create(ctx, gatewayClass)).To(BeNil()) - Eventually(func() error { // gateway class exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gatewayClass.Name}, gatewayClass) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) - - AfterAll(func() { - err := k8sClient.Delete(ctx, gatewayClass) - Expect(err).ToNot(HaveOccurred()) - }) - BeforeEach(func() { CreateNamespace(&testNamespace) + gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") + Expect(k8sClient.Create(ctx, gatewayClass)).To(Succeed()) + managedZone = testutil.NewManagedZoneBuilder("mz-example-com", testNamespace, "example.com").ManagedZone - Expect(k8sClient.Create(ctx, managedZone)).To(BeNil()) - Eventually(func() error { // managed zone exists - return k8sClient.Get(ctx, client.ObjectKey{Name: managedZone.Name, Namespace: managedZone.Namespace}, managedZone) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, managedZone)).To(Succeed()) gateway = testutil.NewGatewayBuilder(TestGatewayName, gatewayClass.Name, testNamespace). WithHTTPListener(TestListenerNameOne, TestHostOne). WithHTTPListener(TestListenerNameWildcard, TestHostWildcard). Gateway - Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) - Eventually(func() error { //gateway exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, gateway)).To(Succeed()) + //Set multi cluster gateway status Eventually(func() error { if err := k8sClient.Create(ctx, &v1.ManagedCluster{ @@ -131,7 +115,6 @@ var _ = Describe("DNSPolicy Multi Cluster", Ordered, func() { err := k8sClient.Delete(ctx, gateway) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) } - if dnsPolicy != nil { err := k8sClient.Delete(ctx, dnsPolicy) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) @@ -141,6 +124,10 @@ var _ = Describe("DNSPolicy Multi Cluster", Ordered, func() { err := k8sClient.Delete(ctx, managedZone) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) } + if gatewayClass != nil { + err := k8sClient.Delete(ctx, gatewayClass) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } }) Context("simple routing strategy", func() { @@ -148,10 +135,7 @@ var _ = Describe("DNSPolicy Multi Cluster", Ordered, func() { BeforeEach(func() { dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy) dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, dnsPolicy)).To(Succeed()) }) It("should create dns records", func() { @@ -209,10 +193,7 @@ var _ = Describe("DNSPolicy Multi Cluster", Ordered, func() { BeforeEach(func() { dnsPolicyBuilder.WithLoadBalancingWeightedFor(120, nil) dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, dnsPolicy)).To(Succeed()) }) It("should create dns records", func() { @@ -342,13 +323,7 @@ var _ = Describe("DNSPolicy Multi Cluster", Ordered, func() { WithLoadBalancingWeightedFor(120, nil). WithLoadBalancingGeoFor("IE") dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - if err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy); err != nil { - return err - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Expect(k8sClient.Create(ctx, dnsPolicy)).To(Succeed()) }) It("should create dns records", func() { @@ -487,437 +462,6 @@ var _ = Describe("DNSPolicy Multi Cluster", Ordered, func() { }) - Context("with health checks", func() { - var unhealthy bool - - BeforeEach(func() { - dnsPolicyBuilder. - WithLoadBalancingWeightedFor(120, nil). - WithHealthCheckFor("/", nil, v1alpha1.HttpProtocol, testutil.Pointer(4)) - dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) - - It("should create a dns record", func() { - createdDNSRecord := &v1alpha1.DNSRecord{} - Eventually(func() error { // DNS record exists - if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord); err != nil { - return err - } - if len(createdDNSRecord.Spec.Endpoints) != 6 { - return fmt.Errorf("expected %v endpoints in DNSRecord, got %v", 6, len(createdDNSRecord.Spec.Endpoints)) - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(6)) - }) - It("should have probes that are healthy", func() { - probeList := &v1alpha1.DNSHealthCheckProbeList{} - Eventually(func() error { - Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) - if len(probeList.Items) != 2 { - return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - Expect(len(probeList.Items)).To(Equal(2)) - }) - - Context("all unhealthy probes", func() { - It("should publish all dns records endpoints", func() { - lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) - - expectedEndpoints := []*v1alpha1.Endpoint{ - { - DNSName: "2w705o.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressTwo, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "s07c46.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressOne, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "2w705o.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "s07c46.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - Labels: nil, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "lb-" + lbHash + ".test.example.com", - Targets: []string{ - "default.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "default", - RecordTTL: 300, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "geo-code", - Value: "*", - }, - }, - }, - { - DNSName: "test.example.com", - Targets: []string{ - "lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "", - RecordTTL: 300, - }, - } - - probeList := &v1alpha1.DNSHealthCheckProbeList{} - Eventually(func() error { - Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) - if len(probeList.Items) != 2 { - return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - - for _, probe := range probeList.Items { - Eventually(func() error { - if probe.Name == fmt.Sprintf("%s-%s-%s", TestIPAddressTwo, TestGatewayName, TestHostOne) || - probe.Name == fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestHostOne) { - getProbe := &v1alpha1.DNSHealthCheckProbe{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: probe.Name, Namespace: probe.Namespace}, getProbe); err != nil { - return err - } - patch := client.MergeFrom(getProbe.DeepCopy()) - unhealthy = false - getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ - LastCheckedAt: metav1.NewTime(time.Now()), - ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, - Healthy: &unhealthy, - } - if err := k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { - return err - } - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - } - createdDNSRecord := &v1alpha1.DNSRecord{} - Eventually(func() error { - - err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) - if err != nil && k8serrors.IsNotFound(err) { - return err - } - if len(createdDNSRecord.Spec.Endpoints) != len(expectedEndpoints) { - return fmt.Errorf("expected %v endpoints in DNSRecord, got %v", len(expectedEndpoints), len(createdDNSRecord.Spec.Endpoints)) - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) - Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) - Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) - - }) - }) - Context("some unhealthy probes", func() { - It("should publish expected endpoints", func() { - lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) - - expectedEndpoints := []*v1alpha1.Endpoint{ - { - DNSName: "2w705o.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressTwo, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "s07c46.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressOne, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "2w705o.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "s07c46.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - Labels: nil, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "lb-" + lbHash + ".test.example.com", - Targets: []string{ - "default.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "default", - RecordTTL: 300, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "geo-code", - Value: "*", - }, - }, - }, - { - DNSName: "test.example.com", - Targets: []string{ - "lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "", - RecordTTL: 300, - }, - } - - probeList := &v1alpha1.DNSHealthCheckProbeList{} - Eventually(func() error { - Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) - if len(probeList.Items) != 2 { - return fmt.Errorf("expected %v probes, got %v", 2, len(probeList.Items)) - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - Expect(probeList.Items).To(HaveLen(2)) - - Eventually(func() error { - getProbe := &v1alpha1.DNSHealthCheckProbe{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestListenerNameOne), Namespace: testNamespace}, getProbe); err != nil { - return err - } - patch := client.MergeFrom(getProbe.DeepCopy()) - unhealthy = false - getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ - LastCheckedAt: metav1.NewTime(time.Now()), - ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, - Healthy: &unhealthy, - } - if err := k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { - return err - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - - // after that verify that in time the endpoints are 5 in the dnsrecord - createdDNSRecord := &v1alpha1.DNSRecord{} - Eventually(func() error { - err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) - if err != nil && k8serrors.IsNotFound(err) { - return err - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) - Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) - Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) - }) - }) - Context("some unhealthy endpoints for other listener", func() { - It("should publish expected endpoints", func() { - lbHash = dns.ToBase36hash(fmt.Sprintf("%s-%s", gateway.Name, gateway.Namespace)) - - expectedEndpoints := []*v1alpha1.Endpoint{ - { - DNSName: "2w705o.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressTwo, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "s07c46.lb-" + lbHash + ".test.example.com", - Targets: []string{ - TestIPAddressOne, - }, - RecordType: "A", - SetIdentifier: "", - RecordTTL: 60, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "2w705o.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "2w705o.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "default.lb-" + lbHash + ".test.example.com", - Targets: []string{ - "s07c46.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "s07c46.lb-" + lbHash + ".test.example.com", - RecordTTL: 60, - Labels: nil, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "weight", - Value: "120", - }, - }, - }, - { - DNSName: "lb-" + lbHash + ".test.example.com", - Targets: []string{ - "default.lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "default", - RecordTTL: 300, - ProviderSpecific: v1alpha1.ProviderSpecific{ - { - Name: "geo-code", - Value: "*", - }, - }, - }, - { - DNSName: "test.example.com", - Targets: []string{ - "lb-" + lbHash + ".test.example.com", - }, - RecordType: "CNAME", - SetIdentifier: "", - RecordTTL: 300, - }, - } - - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) - Expect(err).NotTo(HaveOccurred()) - Expect(gateway.Spec.Listeners).NotTo(BeNil()) - // add another listener, should result in 4 probes - typedHostname := gatewayv1beta1.Hostname(TestHostTwo) - otherListener := gatewayv1beta1.Listener{ - Name: gatewayv1beta1.SectionName(TestListenerNameTwo), - Hostname: &typedHostname, - Port: gatewayv1beta1.PortNumber(80), - Protocol: gatewayv1beta1.HTTPProtocolType, - } - - patch := client.MergeFrom(gateway.DeepCopy()) - gateway.Spec.Listeners = append(gateway.Spec.Listeners, otherListener) - Expect(k8sClient.Patch(ctx, gateway, patch)).To(BeNil()) - - probeList := &v1alpha1.DNSHealthCheckProbeList{} - Eventually(func() error { - Expect(k8sClient.List(ctx, probeList, &client.ListOptions{Namespace: testNamespace})).To(BeNil()) - if len(probeList.Items) != 4 { - return fmt.Errorf("expected %v probes, got %v", 4, len(probeList.Items)) - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - Expect(len(probeList.Items)).To(Equal(4)) - - // - Eventually(func() error { - getProbe := &v1alpha1.DNSHealthCheckProbe{} - if err = k8sClient.Get(ctx, client.ObjectKey{Name: fmt.Sprintf("%s-%s-%s", TestIPAddressOne, TestGatewayName, TestListenerNameTwo), Namespace: testNamespace}, getProbe); err != nil { - return err - } - patch := client.MergeFrom(getProbe.DeepCopy()) - unhealthy = false - getProbe.Status = v1alpha1.DNSHealthCheckProbeStatus{ - LastCheckedAt: metav1.NewTime(time.Now()), - ConsecutiveFailures: *getProbe.Spec.FailureThreshold + 1, - Healthy: &unhealthy, - } - if err = k8sClient.Status().Patch(ctx, getProbe, patch); err != nil { - return err - } - return nil - }, TestTimeoutLong, TestRetryIntervalMedium).Should(BeNil()) - - // after that verify that in time the endpoints are 5 in the dnsrecord - createdDNSRecord := &v1alpha1.DNSRecord{} - Eventually(func() error { - err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord) - if err != nil && k8serrors.IsNotFound(err) { - return err - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - Expect(createdDNSRecord.Spec.Endpoints).To(HaveLen(len(expectedEndpoints))) - Expect(createdDNSRecord.Spec.Endpoints).Should(ContainElements(expectedEndpoints)) - Expect(expectedEndpoints).Should(ContainElements(createdDNSRecord.Spec.Endpoints)) - }) - }) - }) - }) }) diff --git a/test/policy_integration/dnspolicy_controller_single_cluster_test.go b/test/policy_integration/dnspolicy_controller_single_cluster_test.go index 20bbd602..d800f275 100644 --- a/test/policy_integration/dnspolicy_controller_single_cluster_test.go +++ b/test/policy_integration/dnspolicy_controller_single_cluster_test.go @@ -19,7 +19,7 @@ import ( testutil "github.com/Kuadrant/multicluster-gateway-controller/test/util" ) -var _ = Describe("DNSPolicy Single Cluster", Ordered, func() { +var _ = Describe("DNSPolicy Single Cluster", func() { var gatewayClass *gatewayv1beta1.GatewayClass var managedZone *v1alpha1.ManagedZone @@ -29,36 +29,21 @@ var _ = Describe("DNSPolicy Single Cluster", Ordered, func() { var dnsPolicy *v1alpha1.DNSPolicy var lbHash, recordName, wildcardRecordName string - BeforeAll(func() { - gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") - Expect(k8sClient.Create(ctx, gatewayClass)).To(BeNil()) - Eventually(func() error { // gateway class exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gatewayClass.Name}, gatewayClass) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) - - AfterAll(func() { - err := k8sClient.Delete(ctx, gatewayClass) - Expect(err).ToNot(HaveOccurred()) - }) - BeforeEach(func() { CreateNamespace(&testNamespace) + gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") + Expect(k8sClient.Create(ctx, gatewayClass)).To(Succeed()) + managedZone = testutil.NewManagedZoneBuilder("mz-example-com", testNamespace, "example.com").ManagedZone - Expect(k8sClient.Create(ctx, managedZone)).To(BeNil()) - Eventually(func() error { // managed zone exists - return k8sClient.Get(ctx, client.ObjectKey{Name: managedZone.Name, Namespace: managedZone.Namespace}, managedZone) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, managedZone)).To(Succeed()) gateway = testutil.NewGatewayBuilder(TestGatewayName, gatewayClass.Name, testNamespace). WithHTTPListener(TestListenerNameOne, TestHostOne). WithHTTPListener(TestListenerNameWildcard, TestHostWildcard). Gateway - Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) - Eventually(func() error { //gateway exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, gateway)).To(Succeed()) + //Set single cluster gateway status Eventually(func() error { gateway.Status.Addresses = []gatewayv1beta1.GatewayAddress{ @@ -86,7 +71,7 @@ var _ = Describe("DNSPolicy Single Cluster", Ordered, func() { }, } return k8sClient.Status().Update(ctx, gateway) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(Succeed()) dnsPolicyBuilder = testutil.NewDNSPolicyBuilder("test-dns-policy", testNamespace) dnsPolicyBuilder.WithTargetGateway(TestGatewayName) @@ -96,15 +81,32 @@ var _ = Describe("DNSPolicy Single Cluster", Ordered, func() { wildcardRecordName = fmt.Sprintf("%s-%s", TestGatewayName, TestListenerNameWildcard) }) + AfterEach(func() { + if gateway != nil { + err := k8sClient.Delete(ctx, gateway) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } + if dnsPolicy != nil { + err := k8sClient.Delete(ctx, dnsPolicy) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + + } + if managedZone != nil { + err := k8sClient.Delete(ctx, managedZone) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } + if gatewayClass != nil { + err := k8sClient.Delete(ctx, gatewayClass) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } + }) + Context("simple routing strategy", func() { BeforeEach(func() { dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy) dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, dnsPolicy)).To(Succeed()) }) It("should create dns records", func() { @@ -156,10 +158,7 @@ var _ = Describe("DNSPolicy Single Cluster", Ordered, func() { BeforeEach(func() { dnsPolicyBuilder.WithRoutingStrategy(v1alpha1.LoadBalancedRoutingStrategy) dnsPolicy = dnsPolicyBuilder.DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, dnsPolicy)).To(Succeed()) }) It("should create dns records", func() { diff --git a/test/policy_integration/dnspolicy_controller_test.go b/test/policy_integration/dnspolicy_controller_test.go index fca28768..b742fd9c 100644 --- a/test/policy_integration/dnspolicy_controller_test.go +++ b/test/policy_integration/dnspolicy_controller_test.go @@ -4,29 +4,27 @@ package policy_integration import ( "encoding/json" - "errors" "fmt" "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gstruct" v1 "open-cluster-management.io/api/cluster/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" "github.com/Kuadrant/multicluster-gateway-controller/pkg/_internal/conditions" - "github.com/Kuadrant/multicluster-gateway-controller/pkg/_internal/metadata" "github.com/Kuadrant/multicluster-gateway-controller/pkg/apis/v1alpha1" . "github.com/Kuadrant/multicluster-gateway-controller/pkg/controllers/dnspolicy" mgcgateway "github.com/Kuadrant/multicluster-gateway-controller/pkg/controllers/gateway" testutil "github.com/Kuadrant/multicluster-gateway-controller/test/util" ) -var _ = Describe("DNSPolicy", Ordered, func() { +var _ = Describe("DNSPolicy", func() { var gatewayClass *gatewayv1beta1.GatewayClass var managedZone *v1alpha1.ManagedZone @@ -36,21 +34,15 @@ var _ = Describe("DNSPolicy", Ordered, func() { var dnsPolicy *v1alpha1.DNSPolicy var recordName, wildcardRecordName string - BeforeAll(func() { - gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") - Expect(k8sClient.Create(ctx, gatewayClass)).To(BeNil()) - Eventually(func() error { // gateway class exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gatewayClass.Name}, gatewayClass) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - }) - BeforeEach(func() { CreateNamespace(&testNamespace) + + gatewayClass = testutil.NewTestGatewayClass("foo", "default", "kuadrant.io/bar") + Expect(k8sClient.Create(ctx, gatewayClass)).To(Succeed()) + managedZone = testutil.NewManagedZoneBuilder("mz-example-com", testNamespace, "example.com").ManagedZone - Expect(k8sClient.Create(ctx, managedZone)).To(BeNil()) - Eventually(func() error { // managed zone exists - return k8sClient.Get(ctx, client.ObjectKey{Name: managedZone.Name, Namespace: managedZone.Namespace}, managedZone) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, managedZone)).To(Succeed()) + dnsPolicyBuilder = testutil.NewDNSPolicyBuilder("test-dns-policy", testNamespace) }) @@ -68,11 +60,10 @@ var _ = Describe("DNSPolicy", Ordered, func() { err := k8sClient.Delete(ctx, managedZone) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) } - }) - - AfterAll(func() { - err := k8sClient.Delete(ctx, gatewayClass) - Expect(err).ToNot(HaveOccurred()) + if gatewayClass != nil { + err := k8sClient.Delete(ctx, gatewayClass) + Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) + } }) Context("invalid target", func() { @@ -82,32 +73,21 @@ var _ = Describe("DNSPolicy", Ordered, func() { WithTargetGateway("test-gateway"). WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy). DNSPolicy - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, dnsPolicy)).To(Succeed()) }) It("should have ready condition with status false and correct reason", func() { - Eventually(func() error { - if err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy); err != nil { - return err - } - readyCond := meta.FindStatusCondition(dnsPolicy.Status.Conditions, string(conditions.ConditionTypeReady)) - if readyCond == nil { - return fmt.Errorf("expected dnsPolicy to have %s condition, got none", - string(conditions.ConditionTypeReady)) - } - if readyCond.Status != metav1.ConditionFalse { - return fmt.Errorf("expected dnsPolicy %s condition to have status %s, got %s", - string(conditions.ConditionTypeReady), metav1.ConditionFalse, readyCond.Status) - } - if readyCond.Reason != string(conditions.PolicyReasonTargetNotFound) { - return fmt.Errorf("expected dnsPolicy %s condition to have reason %s, got %s", - string(conditions.ConditionTypeReady), string(conditions.PolicyReasonTargetNotFound), readyCond.Reason) - } - return nil - }, time.Second*15, time.Second).Should(BeNil()) + Eventually(func(g Gomega) { + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(dnsPolicy), dnsPolicy) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(dnsPolicy.Status.Conditions).To( + ContainElement(MatchFields(IgnoreExtras, Fields{ + "Type": Equal(string(conditions.ConditionTypeReady)), + "Status": Equal(metav1.ConditionFalse), + "Reason": Equal(string(conditions.PolicyReasonTargetNotFound)), + })), + ) + }, TestTimeoutMedium, time.Second).Should(Succeed()) }) It("should have ready condition with status true", func() { @@ -115,20 +95,19 @@ var _ = Describe("DNSPolicy", Ordered, func() { gateway = testutil.NewGatewayBuilder("test-gateway", gatewayClass.Name, testNamespace). WithHTTPListener("test-listener", "test.example.com").Gateway - Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) - Eventually(func() error { //gateway exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + Expect(k8sClient.Create(ctx, gateway)).To(Succeed()) - Eventually(func() error { - if err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy); err != nil { - return err - } - if !meta.IsStatusConditionTrue(dnsPolicy.Status.Conditions, string(conditions.ConditionTypeReady)) { - return fmt.Errorf("expected dnsPolicy %s condition to have status %s ", string(conditions.ConditionTypeReady), metav1.ConditionTrue) - } - return nil - }, time.Second*15, time.Second).Should(BeNil()) + Eventually(func(g Gomega) { + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(dnsPolicy), dnsPolicy) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(dnsPolicy.Status.Conditions).To( + ContainElement(MatchFields(IgnoreExtras, Fields{ + "Type": Equal(string(conditions.ConditionTypeReady)), + "Status": Equal(metav1.ConditionTrue), + "Reason": Equal("GatewayDNSEnabled"), + })), + ) + }, TestTimeoutMedium, time.Second).Should(Succeed()) }) It("should not have any health check records created", func() { @@ -146,24 +125,16 @@ var _ = Describe("DNSPolicy", Ordered, func() { }, }, } - Expect(k8sClient.Create(ctx, probe)).To(BeNil()) + Expect(k8sClient.Create(ctx, probe)).To(Succeed()) - Eventually(func() error { // probe should be present - getCreatedProbe := &v1alpha1.DNSHealthCheckProbe{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: probe.Name, Namespace: probe.Namespace}, getCreatedProbe) - return err - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) + err := k8sClient.Get(ctx, client.ObjectKey{Name: probe.Name, Namespace: probe.Namespace}, &v1alpha1.DNSHealthCheckProbe{}) + Expect(err).NotTo(HaveOccurred()) - Eventually(func() bool { // probe should be removed - getDeletedProbe := &v1alpha1.DNSHealthCheckProbe{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: probe.Name, Namespace: probe.Namespace}, getDeletedProbe) - if err != nil { - if k8serrors.IsNotFound(err) { - return true - } - } - return false - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeTrue()) + Eventually(func(g Gomega) { // probe should be removed + err := k8sClient.Get(ctx, client.ObjectKey{Name: probe.Name, Namespace: probe.Namespace}, &v1alpha1.DNSHealthCheckProbe{}) + g.Expect(err).To(HaveOccurred()) + g.Expect(err).To(MatchError(ContainSubstring("not found"))) + }, TestTimeoutMedium, time.Second).Should(Succeed()) }) }) @@ -180,16 +151,8 @@ var _ = Describe("DNSPolicy", Ordered, func() { WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy). DNSPolicy - Expect(k8sClient.Create(ctx, gateway)).To(BeNil()) - Expect(k8sClient.Create(ctx, dnsPolicy)).To(BeNil()) - - Eventually(func() error { //gateway exists - return k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) - }, TestTimeoutMedium, TestRetryIntervalMedium).ShouldNot(HaveOccurred()) - - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + Expect(k8sClient.Create(ctx, gateway)).To(Succeed()) + Expect(k8sClient.Create(ctx, dnsPolicy)).To(Succeed()) }) It("should not create a dns record", func() { @@ -202,58 +165,31 @@ var _ = Describe("DNSPolicy", Ordered, func() { }) It("should have ready status", func() { - Eventually(func() error { - if err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy); err != nil { - return err - } - if !meta.IsStatusConditionTrue(dnsPolicy.Status.Conditions, string(conditions.ConditionTypeReady)) { - return fmt.Errorf("expected DNSPolicy status condition to be %s", string(conditions.ConditionTypeReady)) - } - return nil - }, time.Second*15, time.Second).Should(BeNil()) + Eventually(func(g Gomega) { + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(dnsPolicy), dnsPolicy) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(dnsPolicy.Status.Conditions).To( + ContainElement(MatchFields(IgnoreExtras, Fields{ + "Type": Equal(string(conditions.ConditionTypeReady)), + "Status": Equal(metav1.ConditionTrue), + "Reason": Equal("GatewayDNSEnabled"), + })), + ) + }, TestTimeoutMedium, time.Second).Should(Succeed()) }) It("should set gateway back reference", func() { - existingGateway := &gatewayv1beta1.Gateway{} policyBackRefValue := testNamespace + "/" + dnsPolicy.Name refs, _ := json.Marshal([]client.ObjectKey{{Name: dnsPolicy.Name, Namespace: testNamespace}}) policiesBackRefValue := string(refs) - Eventually(func() error { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - if err != nil { - return err - } - annotations := existingGateway.GetAnnotations() - if annotations == nil { - return fmt.Errorf("existingGateway annotations should not be nil") - } - if _, ok := annotations[DNSPolicyBackRefAnnotation]; !ok { - return fmt.Errorf("existingGateway annotations do not have annotation %s", DNSPolicyBackRefAnnotation) - } - if annotations[DNSPolicyBackRefAnnotation] != policyBackRefValue { - return fmt.Errorf("existingGateway annotations[%s] does not have expected value", DNSPolicyBackRefAnnotation) - } - return nil - }, time.Second*5, time.Second).Should(BeNil()) - Eventually(func() error { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - if err != nil { - return err - } - annotations := existingGateway.GetAnnotations() - if annotations == nil { - return fmt.Errorf("existingGateway annotations should not be nil") - } - if _, ok := annotations[DNSPoliciesBackRefAnnotation]; !ok { - return fmt.Errorf("existingGateway annotations do not have annotation %s", DNSPoliciesBackRefAnnotation) - } - if annotations[DNSPoliciesBackRefAnnotation] != policiesBackRefValue { - return fmt.Errorf("existingGateway annotations[%s] does not have expected value", DNSPoliciesBackRefAnnotation) - } - return nil - }, time.Second*5, time.Second).Should(BeNil()) + + Eventually(func(g Gomega) { + gw := &gatewayv1beta1.Gateway{} + err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, gw) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(gw.Annotations).To(HaveKeyWithValue(DNSPolicyBackRefAnnotation, policyBackRefValue)) + g.Expect(gw.Annotations).To(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) + }, TestTimeoutMedium, time.Second).Should(Succeed()) }) }) @@ -266,16 +202,11 @@ var _ = Describe("DNSPolicy", Ordered, func() { Gateway dnsPolicy = dnsPolicyBuilder.WithTargetGateway(TestGatewayName). WithRoutingStrategy(v1alpha1.SimpleRoutingStrategy). - //WithLoadBalancingWeightedFor(120, nil). DNSPolicy Expect(k8sClient.Create(ctx, gateway)).To(Succeed()) Expect(k8sClient.Create(ctx, dnsPolicy)).To(Succeed()) - Eventually(func() error { //dns policy exists - return k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy) - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) - Eventually(func() error { if err := k8sClient.Create(ctx, &v1.ManagedCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -292,7 +223,7 @@ var _ = Describe("DNSPolicy", Ordered, func() { return err } - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, gateway) + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), gateway) Expect(err).ShouldNot(HaveOccurred()) gateway.Status.Addresses = []gatewayv1beta1.GatewayAddress{ @@ -339,52 +270,41 @@ var _ = Describe("DNSPolicy", Ordered, func() { }) It("should have correct status", func() { - Eventually(func() error { - if err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: dnsPolicy.Namespace}, dnsPolicy); err != nil { - return err - } - if !meta.IsStatusConditionTrue(dnsPolicy.Status.Conditions, string(conditions.ConditionTypeReady)) { - return fmt.Errorf("expected status condition %s to be True", conditions.ConditionTypeReady) - } - if err := k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), gateway); err != nil { - return err - } - - policyAffectedCond := meta.FindStatusCondition(gateway.Status.Conditions, string(DNSPolicyAffected)) - if policyAffectedCond == nil { - return fmt.Errorf("policy affected conditon expected but not found") - } - if policyAffectedCond.ObservedGeneration != gateway.Generation { - return fmt.Errorf("expected policy affected cond generation to be %d but got %d", gateway.Generation, policyAffectedCond.ObservedGeneration) - } - if !meta.IsStatusConditionTrue(gateway.Status.Conditions, string(DNSPolicyAffected)) { - return fmt.Errorf("expected gateway status condition %s to be True", DNSPolicyAffected) - } - - return nil - }, time.Second*15, time.Second).Should(BeNil()) + Eventually(func(g Gomega) { + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(dnsPolicy), dnsPolicy) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(dnsPolicy.Finalizers).To(ContainElement(DNSPolicyFinalizer)) + g.Expect(dnsPolicy.Status.Conditions).To( + ContainElement(MatchFields(IgnoreExtras, Fields{ + "Type": Equal(string(conditions.ConditionTypeReady)), + "Status": Equal(metav1.ConditionTrue), + "Reason": Equal("GatewayDNSEnabled"), + })), + ) + err = k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), gateway) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(gateway.Status.Conditions).To( + ContainElement(MatchFields(IgnoreExtras, Fields{ + "Type": Equal(string(DNSPolicyAffected)), + "Status": Equal(metav1.ConditionTrue), + "Reason": Equal(string(conditions.PolicyReasonAccepted)), + "ObservedGeneration": Equal(gateway.Generation), + })), + ) + }, TestTimeoutMedium, time.Second).Should(Succeed()) }) It("should set gateway back reference", func() { - existingGateway := &gatewayv1beta1.Gateway{} policyBackRefValue := testNamespace + "/" + dnsPolicy.Name refs, _ := json.Marshal([]client.ObjectKey{{Name: dnsPolicy.Name, Namespace: testNamespace}}) policiesBackRefValue := string(refs) - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPolicyBackRefAnnotation, policyBackRefValue)) - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) + Eventually(func(g Gomega) { + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), gateway) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(gateway.Annotations).To(HaveKeyWithValue(DNSPolicyBackRefAnnotation, policyBackRefValue)) + g.Expect(gateway.Annotations).To(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) + }, TestTimeoutMedium, time.Second).Should(Succeed()) }) It("should remove dns records when listener removed", func() { @@ -417,74 +337,50 @@ var _ = Describe("DNSPolicy", Ordered, func() { }) It("should remove gateway back reference on policy deletion", func() { - existingGateway := &gatewayv1beta1.Gateway{} policyBackRefValue := testNamespace + "/" + dnsPolicy.Name refs, _ := json.Marshal([]client.ObjectKey{{Name: dnsPolicy.Name, Namespace: testNamespace}}) policiesBackRefValue := string(refs) - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPolicyBackRefAnnotation, policyBackRefValue)) - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).Should(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) - - //finalizer should exist - Eventually(func() bool { - existingDNSPolicy := &v1alpha1.DNSPolicy{} - err := k8sClient.Get(ctx, client.ObjectKey{Name: dnsPolicy.Name, Namespace: testNamespace}, existingDNSPolicy) - // must exist - Expect(err).ToNot(HaveOccurred()) - return metadata.HasFinalizer(existingDNSPolicy, DNSPolicyFinalizer) - }, time.Second*5, time.Second).Should(BeTrue()) - + Eventually(func(g Gomega) { + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), gateway) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(gateway.Annotations).To(HaveKeyWithValue(DNSPolicyBackRefAnnotation, policyBackRefValue)) + g.Expect(gateway.Annotations).To(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) + g.Expect(gateway.Status.Conditions).To( + ContainElement(MatchFields(IgnoreExtras, Fields{ + "Type": Equal(string(DNSPolicyAffected)), + "Status": Equal(metav1.ConditionTrue), + "Reason": Equal(string(conditions.PolicyReasonAccepted)), + "ObservedGeneration": Equal(gateway.Generation), + })), + ) + + err = k8sClient.Get(ctx, client.ObjectKeyFromObject(dnsPolicy), dnsPolicy) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(dnsPolicy.Finalizers).To(ContainElement(DNSPolicyFinalizer)) + }, TestTimeoutMedium, time.Second).Should(Succeed()) + + By("deleting the dns policy") Expect(k8sClient.Delete(ctx, dnsPolicy)).To(BeNil()) - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: gateway.Namespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).ShouldNot(HaveKey(DNSPolicyBackRefAnnotation)) - - Eventually(func() map[string]string { - // Check gateway back references - err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway) - // must exist - Expect(err).ToNot(HaveOccurred()) - return existingGateway.GetAnnotations() - }, time.Second*5, time.Second).ShouldNot(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) - - Eventually(func() error { - // Check gateway back references - if err := k8sClient.Get(ctx, client.ObjectKey{Name: gateway.Name, Namespace: testNamespace}, existingGateway); err != nil { - return err - } - cond := meta.FindStatusCondition(existingGateway.Status.Conditions, string(DNSPolicyAffected)) - if cond != nil { - return fmt.Errorf("expected the condition %s to be gone", DNSPolicyAffected) - } - return nil - }, time.Second*5, time.Second).Should(BeNil()) + Eventually(func(g Gomega) { + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), gateway) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(gateway.Annotations).ToNot(HaveKey(DNSPolicyBackRefAnnotation)) + g.Expect(gateway.Annotations).ToNot(HaveKeyWithValue(DNSPoliciesBackRefAnnotation, policiesBackRefValue)) + g.Expect(gateway.Status.Conditions).ToNot( + ContainElement(MatchFields(IgnoreExtras, Fields{ + "Type": Equal(string(DNSPolicyAffected)), + })), + ) + }, TestTimeoutMedium, time.Second).Should(Succeed()) }) It("should remove dns record reference on policy deletion even if gateway is removed", func() { - createdDNSRecord := &v1alpha1.DNSRecord{} + Eventually(func() error { // DNS record exists - if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord); err != nil { - return err - } - return nil - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + return k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, &v1alpha1.DNSRecord{}) + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(Succeed()) err := k8sClient.Delete(ctx, gateway) Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) @@ -493,14 +389,9 @@ var _ = Describe("DNSPolicy", Ordered, func() { Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred()) Eventually(func() error { // DNS record removed - if err := k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, createdDNSRecord); err != nil { - if k8serrors.IsNotFound(err) { - return nil - } - return err - } - return errors.New("found dnsrecord when it should be deleted") - }, TestTimeoutMedium, TestRetryIntervalMedium).Should(BeNil()) + return k8sClient.Get(ctx, client.ObjectKey{Name: recordName, Namespace: testNamespace}, &v1alpha1.DNSRecord{}) + }, TestTimeoutMedium, TestRetryIntervalMedium).Should(MatchError(ContainSubstring("not found"))) + }) })