diff --git a/controllers/ingress/controller_integration_test.go b/controllers/ingress/controller_integration_test.go index 2f963388..8f0e8a51 100644 --- a/controllers/ingress/controller_integration_test.go +++ b/controllers/ingress/controller_integration_test.go @@ -603,6 +603,60 @@ func (s *ControllerTestSuite) TestIngressStatus() { return true }, time.Minute, time.Second) } +func (s *ControllerTestSuite) TestIngressAddressWithNodeport() { + ctx := context.Background() + + proxySvcName := types.NamespacedName{Name: "pomerium-proxy", Namespace: "pomerium"} + s.createTestController(ctx, + ingress_controller.WithNamespaces([]string{"default"}), + ingress_controller.WithUpdateIngressStatusFromService(proxySvcName), + ) + + ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "pomerium"}} + proxySvc := &corev1.Service{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: proxySvcName.Name, + Namespace: proxySvcName.Namespace, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeNodePort, + Ports: []corev1.ServicePort{{ + Name: "https", + Protocol: "TCP", + Port: 443, + TargetPort: intstr.FromInt(5443), + }}, + }, + } + to := s.initialTestObjects("default") + class, ingress, endpoints, service, secret := to.IngressClass, to.Ingress, to.Endpoints, to.Service, to.Secret + del := func(obj client.Object) { s.Client.Delete(ctx, obj) } + for _, obj := range []client.Object{ + ns, proxySvc, + class, endpoints, service, secret, ingress, + } { + s.NoError(s.Client.Create(ctx, obj)) + defer del(obj) + } + + s.EventuallyUpsert(func(ic *model.IngressConfig) string { + return cmp.Diff(ingress, ic.Ingress, cmpOpts...) + }, "ingress created") + + proxySvc.Spec.ClusterIP = "10.0.0.1" + s.NoError(s.Client.Status().Update(ctx, proxySvc), proxySvc.Spec) + require.Eventually(s.T(), func() bool { + s.NoError(s.Client.Get(ctx, types.NamespacedName{Name: ingress.Name, Namespace: ingress.Namespace}, ingress)) + if len(ingress.Status.LoadBalancer.Ingress) != 1 { + return false + } + if ingress.Status.LoadBalancer.Ingress[0].IP != proxySvc.Spec.ClusterIP { + return false + } + return true + }, time.Minute, time.Second) +} func (s *ControllerTestSuite) TestHttp01Solver() { ctx := context.Background() diff --git a/controllers/ingress/reconcile.go b/controllers/ingress/reconcile.go index 4cfcaacd..73d2a6c0 100644 --- a/controllers/ingress/reconcile.go +++ b/controllers/ingress/reconcile.go @@ -142,21 +142,29 @@ func (r *ingressController) updateIngressStatus(ctx context.Context, ingress *ne } ingress.Status.LoadBalancer = networkingv1.IngressLoadBalancerStatus{ - Ingress: svcLoadBalancerStatusToIngress(svc.Status.LoadBalancer.Ingress), + Ingress: svcStatusToIngress(svc), } + return r.Client.Status().Update(ctx, ingress) } -func svcLoadBalancerStatusToIngress(src []corev1.LoadBalancerIngress) []networkingv1.IngressLoadBalancerIngress { - dst := make([]networkingv1.IngressLoadBalancerIngress, len(src)) - for i := range src { - dst[i] = networkingv1.IngressLoadBalancerIngress{ - Hostname: src[i].Hostname, - IP: src[i].IP, - Ports: svcPortToIngress(src[i].Ports), +func svcStatusToIngress(svc *corev1.Service) []networkingv1.IngressLoadBalancerIngress { + if svc.Spec.Type == corev1.ServiceTypeLoadBalancer { + var src = svc.Status.LoadBalancer.Ingress + dst := make([]networkingv1.IngressLoadBalancerIngress, len(src)) + for i := range src { + dst[i] = networkingv1.IngressLoadBalancerIngress{ + Hostname: src[i].Hostname, + IP: src[i].IP, + Ports: svcPortToIngress(src[i].Ports), + } } + return dst } - return dst + // Assign ClusterIP for NodePort service + return []networkingv1.IngressLoadBalancerIngress{{ + IP: svc.Spec.ClusterIP, + }} } func svcPortToIngress(src []corev1.PortStatus) []networkingv1.IngressPortStatus {