From 025da4abe20f722b13b8d0c4e4d9db5acd68fb32 Mon Sep 17 00:00:00 2001 From: Erik Rasmussen Date: Fri, 19 Jan 2024 14:58:07 -0600 Subject: [PATCH] Addressing PR comments Missed some stuff --- pkg/cloudflare-controller/tunnel-client.go | 4 + pkg/controller/ingress-controller.go | 17 +- pkg/controller/transform.go | 13 - .../controller/ingress_transform_test.go | 338 ------------------ 4 files changed, 19 insertions(+), 353 deletions(-) diff --git a/pkg/cloudflare-controller/tunnel-client.go b/pkg/cloudflare-controller/tunnel-client.go index 72abff3..df475a6 100644 --- a/pkg/cloudflare-controller/tunnel-client.go +++ b/pkg/cloudflare-controller/tunnel-client.go @@ -35,6 +35,10 @@ func (t *TunnelClient) PutExposures(ctx context.Context, exposures []exposure.Ex return nil } +func (t *TunnelClient) TunnelDomain() string { + return tunnelDomain(t.tunnelId) +} + func (t *TunnelClient) updateTunnelIngressRules(ctx context.Context, exposures []exposure.Exposure) error { var ingressRules []cloudflare.UnvalidatedIngressRule diff --git a/pkg/controller/ingress-controller.go b/pkg/controller/ingress-controller.go index 9180611..3b82107 100644 --- a/pkg/controller/ingress-controller.go +++ b/pkg/controller/ingress-controller.go @@ -3,11 +3,11 @@ package controller import ( "context" "fmt" - cloudflarecontroller "github.com/STRRL/cloudflare-tunnel-ingress-controller/pkg/cloudflare-controller" "github.com/STRRL/cloudflare-tunnel-ingress-controller/pkg/exposure" "github.com/go-logr/logr" "github.com/pkg/errors" + v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/client" @@ -99,6 +99,19 @@ func (i *IngressController) Reconcile(ctx context.Context, request reconcile.Req } } + origin.Status.LoadBalancer.Ingress = append(origin.Status.LoadBalancer.Ingress, + networkingv1.IngressLoadBalancerIngress{ + Hostname: i.tunnelClient.TunnelDomain(), + Ports: []networkingv1.IngressPortStatus{{ + Protocol: v1.ProtocolTCP, + Port: 443, + }}, + }, + ) + if err = i.kubeClient.Status().Update(ctx, &origin); err != nil { + return reconcile.Result{}, errors.Wrapf(err, "failed to update ingress status") + } + i.logger.V(3).Info("reconcile completed", "triggered-by", request.NamespacedName) return reconcile.Result{}, nil } @@ -135,7 +148,7 @@ func (i *IngressController) listControlledIngressClasses(ctx context.Context) ([ if err != nil { return nil, errors.Wrap(err, "list ingress classes") } - + filteredList := make([]networkingv1.IngressClass, 0, len(list.Items)) for _, ingress := range list.Items { if ingress.Spec.Controller != i.controllerClassName { diff --git a/pkg/controller/transform.go b/pkg/controller/transform.go index daa799f..a3f6500 100644 --- a/pkg/controller/transform.go +++ b/pkg/controller/transform.go @@ -102,19 +102,6 @@ func FromIngressToExposure(ctx context.Context, logger logr.Logger, kubeClient c IsDeleted: isDeleted, ProxySSLVerifyEnabled: proxySSLVerifyEnabled, }) - - if service.Status.LoadBalancer.Ingress == nil { - service.Status.LoadBalancer.Ingress = []v1.LoadBalancerIngress{{Hostname: hostname}} - } else { - service.Status.LoadBalancer.Ingress = append(service.Status.LoadBalancer.Ingress, v1.LoadBalancerIngress{ - Hostname: hostname, - }) - } - - err = kubeClient.Status().Update(ctx, &service) - if err != nil { - return nil, errors.Wrapf(err, "update service %s", service.Name) - } } } diff --git a/test/integration/controller/ingress_transform_test.go b/test/integration/controller/ingress_transform_test.go index c2f36ab..cb3f6a6 100644 --- a/test/integration/controller/ingress_transform_test.go +++ b/test/integration/controller/ingress_transform_test.go @@ -12,7 +12,6 @@ import ( v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -184,10 +183,6 @@ var _ = Describe("transform ingress to exposure", func() { exposure, err := controller.FromIngressToExposure(ctx, logger, kubeClient, ingress) Expect(err).Should(HaveOccurred()) Expect(exposure).Should(BeNil()) - - err = kubeClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: service.Name}, &service) - Expect(err).ShouldNot(HaveOccurred()) - Expect(service.Status.LoadBalancer.Ingress).Should(BeEmpty()) }) It("should fail fast with PathType ImplementationSpecific", func() { @@ -266,10 +261,6 @@ var _ = Describe("transform ingress to exposure", func() { exposure, err := controller.FromIngressToExposure(ctx, logger, kubeClient, ingress) Expect(err).Should(HaveOccurred()) Expect(exposure).Should(BeNil()) - - err = kubeClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: service.Name}, &service) - Expect(err).ShouldNot(HaveOccurred()) - Expect(service.Status.LoadBalancer.Ingress).Should(BeEmpty()) }) It("should resolve ingress with port name", func() { @@ -431,10 +422,6 @@ var _ = Describe("transform ingress to exposure", func() { exposure, err := controller.FromIngressToExposure(ctx, logger, kubeClient, ingress) Expect(err).Should(HaveOccurred()) Expect(exposure).Should(BeNil()) - - err = kubeClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: service.Name}, &service) - Expect(err).ShouldNot(HaveOccurred()) - Expect(service.Status.LoadBalancer.Ingress).Should(BeEmpty()) }) It("should fail fast with headless service", func() { @@ -513,10 +500,6 @@ var _ = Describe("transform ingress to exposure", func() { exposure, err := controller.FromIngressToExposure(ctx, logger, kubeClient, ingress) Expect(err).Should(HaveOccurred()) Expect(exposure).Should(BeNil()) - - err = kubeClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: service.Name}, &service) - Expect(err).ShouldNot(HaveOccurred()) - Expect(service.Status.LoadBalancer.Ingress).Should(BeEmpty()) }) It("should resolve https", func() { @@ -783,325 +766,4 @@ var _ = Describe("transform ingress to exposure", func() { Expect(exposure[0].ProxySSLVerifyEnabled).ShouldNot(BeNil()) Expect(*exposure[0].ProxySSLVerifyEnabled).Should(BeTrue()) }) - - It("should update service load balancer ingress hostname", func() { - // prepare - By("preparing namespace") - namespaceFixtures := fixtures.NewKubernetesNamespaceFixtures(IntegrationTestNamespace, kubeClient) - ns, err := namespaceFixtures.Start(ctx) - Expect(err).ShouldNot(HaveOccurred()) - expectedHostname := "test.example.com" - - defer func() { - By("cleaning up namespace") - err := namespaceFixtures.Stop(ctx) - Expect(err).ShouldNot(HaveOccurred()) - }() - - By("preparing service") - service := v1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: ns, - GenerateName: "test-service-", - }, - Spec: v1.ServiceSpec{ - Ports: []v1.ServicePort{ - { - Name: "http", - Protocol: v1.ProtocolTCP, - Port: 2333, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 8080, - }, - }, - }, - }, - } - err = kubeClient.Create(ctx, &service) - Expect(err).ShouldNot(HaveOccurred()) - - By("preparing ingress") - ingress := networkingv1.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: ns, - GenerateName: "test-ingress-", - }, - Spec: networkingv1.IngressSpec{ - Rules: []networkingv1.IngressRule{ - { - Host: expectedHostname, - IngressRuleValue: networkingv1.IngressRuleValue{ - HTTP: &networkingv1.HTTPIngressRuleValue{ - Paths: []networkingv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathTypePrefix, - Backend: networkingv1.IngressBackend{ - Service: &networkingv1.IngressServiceBackend{ - Name: service.Name, - Port: networkingv1.ServiceBackendPort{ - Number: 2333, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } - err = kubeClient.Create(ctx, &ingress) - Expect(err).ShouldNot(HaveOccurred()) - - By("transforming ingress to exposure") - exposure, err := controller.FromIngressToExposure(ctx, logger, kubeClient, ingress) - Expect(err).ShouldNot(HaveOccurred()) - Expect(exposure).ShouldNot(BeNil()) - - err = kubeClient.Get(ctx, types.NamespacedName{ - Namespace: ns, - Name: service.Name, - }, &service) - Expect(err).ShouldNot(HaveOccurred()) - Expect(service.Status.LoadBalancer.Ingress).Should(ContainElement(v1.LoadBalancerIngress{Hostname: expectedHostname})) - }) - - It("should support multiple service backends", func() { - // prepare - By("preparing namespace") - namespaceFixtures := fixtures.NewKubernetesNamespaceFixtures(IntegrationTestNamespace, kubeClient) - ns, err := namespaceFixtures.Start(ctx) - Expect(err).ShouldNot(HaveOccurred()) - expectedHostname1 := "test1.example.com" - expectedHostname2 := "test2.example.com" - - defer func() { - By("cleaning up namespace") - err := namespaceFixtures.Stop(ctx) - Expect(err).ShouldNot(HaveOccurred()) - }() - - By("preparing service 1") - service1 := v1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: ns, - GenerateName: "test-service1-", - }, - Spec: v1.ServiceSpec{ - Ports: []v1.ServicePort{ - { - Name: "http", - Protocol: v1.ProtocolTCP, - Port: 2333, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 8080, - }, - }, - }, - }, - } - err = kubeClient.Create(ctx, &service1) - Expect(err).ShouldNot(HaveOccurred()) - - By("preparing service 2") - service2 := v1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: ns, - GenerateName: "test-service2-", - }, - Spec: v1.ServiceSpec{ - Ports: []v1.ServicePort{ - { - Name: "http", - Protocol: v1.ProtocolTCP, - Port: 2334, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 8088, - }, - }, - }, - }, - } - err = kubeClient.Create(ctx, &service2) - Expect(err).ShouldNot(HaveOccurred()) - - By("preparing ingress") - ingress := networkingv1.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: ns, - GenerateName: "test-ingress-", - }, - Spec: networkingv1.IngressSpec{ - Rules: []networkingv1.IngressRule{ - { - Host: expectedHostname1, - IngressRuleValue: networkingv1.IngressRuleValue{ - HTTP: &networkingv1.HTTPIngressRuleValue{ - Paths: []networkingv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathTypePrefix, - Backend: networkingv1.IngressBackend{ - Service: &networkingv1.IngressServiceBackend{ - Name: service1.Name, - Port: networkingv1.ServiceBackendPort{ - Number: 2333, - }, - }, - }, - }, - }, - }, - }, - }, - { - Host: expectedHostname2, - IngressRuleValue: networkingv1.IngressRuleValue{ - HTTP: &networkingv1.HTTPIngressRuleValue{ - Paths: []networkingv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathTypePrefix, - Backend: networkingv1.IngressBackend{ - Service: &networkingv1.IngressServiceBackend{ - Name: service2.Name, - Port: networkingv1.ServiceBackendPort{ - Number: 2334, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } - err = kubeClient.Create(ctx, &ingress) - Expect(err).ShouldNot(HaveOccurred()) - - By("transforming ingress to exposure") - exposure, err := controller.FromIngressToExposure(ctx, logger, kubeClient, ingress) - Expect(err).ShouldNot(HaveOccurred()) - Expect(exposure).ShouldNot(BeNil()) - - err = kubeClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: service1.Name}, &service1) - Expect(err).ShouldNot(HaveOccurred()) - Expect(service1.Status.LoadBalancer.Ingress).Should(ContainElement(v1.LoadBalancerIngress{Hostname: expectedHostname1})) - - err = kubeClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: service2.Name}, &service2) - Expect(err).ShouldNot(HaveOccurred()) - Expect(service2.Status.LoadBalancer.Ingress).Should(ContainElement(v1.LoadBalancerIngress{Hostname: expectedHostname2})) - }) - - It("should support multiple hosts on a single service", func() { - // prepare - By("preparing namespace") - namespaceFixtures := fixtures.NewKubernetesNamespaceFixtures(IntegrationTestNamespace, kubeClient) - ns, err := namespaceFixtures.Start(ctx) - Expect(err).ShouldNot(HaveOccurred()) - expectedHostname1 := "test1.example.com" - expectedHostname2 := "test2.example.com" - - defer func() { - By("cleaning up namespace") - err := namespaceFixtures.Stop(ctx) - Expect(err).ShouldNot(HaveOccurred()) - }() - - By("preparing service") - service := v1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: ns, - GenerateName: "test-service-", - }, - Spec: v1.ServiceSpec{ - Ports: []v1.ServicePort{ - { - Name: "http", - Protocol: v1.ProtocolTCP, - Port: 2333, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 8080, - }, - }, - }, - }, - } - err = kubeClient.Create(ctx, &service) - Expect(err).ShouldNot(HaveOccurred()) - - By("preparing ingress") - ingress := networkingv1.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: ns, - GenerateName: "test-ingress-", - }, - Spec: networkingv1.IngressSpec{ - Rules: []networkingv1.IngressRule{ - { - Host: expectedHostname1, - IngressRuleValue: networkingv1.IngressRuleValue{ - HTTP: &networkingv1.HTTPIngressRuleValue{ - Paths: []networkingv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathTypePrefix, - Backend: networkingv1.IngressBackend{ - Service: &networkingv1.IngressServiceBackend{ - Name: service.Name, - Port: networkingv1.ServiceBackendPort{ - Number: 2333, - }, - }, - }, - }, - }, - }, - }, - }, - { - Host: expectedHostname2, - IngressRuleValue: networkingv1.IngressRuleValue{ - HTTP: &networkingv1.HTTPIngressRuleValue{ - Paths: []networkingv1.HTTPIngressPath{ - { - Path: "/", - PathType: &pathTypePrefix, - Backend: networkingv1.IngressBackend{ - Service: &networkingv1.IngressServiceBackend{ - Name: service.Name, - Port: networkingv1.ServiceBackendPort{ - Number: 2334, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } - err = kubeClient.Create(ctx, &ingress) - Expect(err).ShouldNot(HaveOccurred()) - - By("transforming ingress to exposure") - exposure, err := controller.FromIngressToExposure(ctx, logger, kubeClient, ingress) - Expect(err).ShouldNot(HaveOccurred()) - Expect(exposure).ShouldNot(BeNil()) - - err = kubeClient.Get(ctx, types.NamespacedName{Namespace: ns, Name: service.Name}, &service) - Expect(err).ShouldNot(HaveOccurred()) - Expect(service.Status.LoadBalancer.Ingress).Should(ContainElement(v1.LoadBalancerIngress{Hostname: expectedHostname1})) - Expect(service.Status.LoadBalancer.Ingress).Should(ContainElement(v1.LoadBalancerIngress{Hostname: expectedHostname2})) - }) })