diff --git a/pkg/kube/wrappers/ingress.go b/pkg/kube/wrappers/ingress.go index b81071ca..12f80162 100644 --- a/pkg/kube/wrappers/ingress.go +++ b/pkg/kube/wrappers/ingress.go @@ -72,50 +72,70 @@ func (iw *IngressWrapper) GetURL() string { return parsedURL.String() } - if !iw.rulesExist() { - logger.Warn("No rules exist in ingress: ", iw.ingress.GetName()) - return "" - } - var url string - if host, exists := iw.tryGetTLSHost(); exists { // Get TLS Host if it exists - url = host + if host, exists := iw.tryGetTLSHost(); exists { // Get TLS Host if defined + url = "https://" + host + } else if host, exists := iw.tryGetRuleHost(); exists { // Fallback to normal host if defined + url = "http://" + host + } else if host, exists := iw.tryGetStatusHost(); exists { // Fallback to status host if defined + url = "http://" + host } else { - url = iw.getHost() // Fallback for normal Host + logger.Warn("Unable to infer host for ingress: ", iw.ingress.GetName()) + return "" } - // Append port + ingressSubPath + // Append path if defined url += iw.getIngressSubPath() return url } -func (iw *IngressWrapper) rulesExist() bool { - return len(iw.ingress.Spec.Rules) > 0 +func (iw *IngressWrapper) supportsTLS() bool { + return len(iw.ingress.Spec.TLS) > 0 } func (iw *IngressWrapper) tryGetTLSHost() (string, bool) { if iw.supportsTLS() && len(iw.ingress.Spec.TLS[0].Hosts) > 0 { - return "https://" + iw.ingress.Spec.TLS[0].Hosts[0], true + return iw.ingress.Spec.TLS[0].Hosts[0], true } + return "", false +} +func (iw *IngressWrapper) rulesExist() bool { + return len(iw.ingress.Spec.Rules) > 0 +} + +func (iw *IngressWrapper) tryGetRuleHost() (string, bool) { + if iw.rulesExist() && iw.ingress.Spec.Rules[0].Host != "" { + return iw.ingress.Spec.Rules[0].Host, true + } return "", false } -func (iw *IngressWrapper) supportsTLS() bool { - return len(iw.ingress.Spec.TLS) > 0 +func (iw *IngressWrapper) statusLoadBalancerExist() bool { + return len(iw.ingress.Status.LoadBalancer.Ingress) > 0 } -func (iw *IngressWrapper) getHost() string { - return "http://" + iw.ingress.Spec.Rules[0].Host +func (iw *IngressWrapper) tryGetStatusHost() (string, bool) { + if iw.statusLoadBalancerExist() { + ingressStatus := iw.ingress.Status.LoadBalancer.Ingress[0] + if ingressStatus.Hostname != "" { + return ingressStatus.Hostname, true + } else if ingressStatus.IP != "" { + return ingressStatus.IP, true + } + } + return "", false } func (iw *IngressWrapper) getIngressSubPath() string { - rule := iw.ingress.Spec.Rules[0] - if rule.HTTP != nil { - if len(rule.HTTP.Paths) > 0 { - return rule.HTTP.Paths[0].Path + if iw.rulesExist() { + rule := iw.ingress.Spec.Rules[0] + if rule.HTTP != nil { + if len(rule.HTTP.Paths) > 0 { + return rule.HTTP.Paths[0].Path + } } } return "" diff --git a/pkg/kube/wrappers/ingress_test.go b/pkg/kube/wrappers/ingress_test.go index 572c07f5..b573c2a6 100644 --- a/pkg/kube/wrappers/ingress_test.go +++ b/pkg/kube/wrappers/ingress_test.go @@ -167,9 +167,9 @@ func TestIngressWrapper_GetURL(t *testing.T) { { name: "IngressWithTLSHostButNoHost", fields: fields{ - ingress: testutil.CreateIngressWithTLSHost("someIngress2", "https://google.com"), + ingress: testutil.CreateIngressWithTLSHost("someIngress2", "google.com"), }, - want: "", + want: "https://google.com", }, { name: "IngressWithTLSHostAndNormalHost", @@ -199,6 +199,20 @@ func TestIngressWrapper_GetURL(t *testing.T) { }, want: "", }, + { + name: "IngressWithStatusHostnameHostButNoHostNorTLSHost", + fields: fields{ + ingress: testutil.CreateIngressWithStatusHostnameHost("someIngress2", "google.com"), + }, + want: "http://google.com", + }, + { + name: "IngressWithStatusIPHostButNoHostNorTLSHost", + fields: fields{ + ingress: testutil.CreateIngressWithStatusIPHost("someIngress2", "1.1.1.1"), + }, + want: "http://1.1.1.1", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -271,7 +285,7 @@ func TestIngressWrapper_tryGetTLSHost(t *testing.T) { fields: fields{ ingress: testutil.CreateIngressWithHostAndTLSHost("someIngress", "google.com", "google.com"), }, - want: "https://google.com", + want: "google.com", want1: true, }, { @@ -335,7 +349,7 @@ func TestIngressWrapper_supportsTLS(t *testing.T) { } } -func TestIngressWrapper_getHost(t *testing.T) { +func TestIngressWrapper_tryGetRuleHost(t *testing.T) { type fields struct { ingress *v1.Ingress } @@ -343,20 +357,23 @@ func TestIngressWrapper_getHost(t *testing.T) { name string fields fields want string + want1 bool }{ { name: "IngressWithEmptyHost", fields: fields{ ingress: testutil.CreateIngressWithHost("someIngress", ""), }, - want: "http://", + want: "", + want1: false, }, { name: "IngressWithCorrectHost", fields: fields{ ingress: testutil.CreateIngressWithHost("someIngress", "google.com"), }, - want: "http://google.com", + want: "google.com", + want1: true, }, } for _, tt := range tests { @@ -364,8 +381,63 @@ func TestIngressWrapper_getHost(t *testing.T) { iw := &IngressWrapper{ ingress: tt.fields.ingress, } - if got := iw.getHost(); got != tt.want { - t.Errorf("IngressWrapper.getHost() = %v, want %v", got, tt.want) + got, got1 := iw.tryGetRuleHost() + if got != tt.want { + t.Errorf("IngressWrapper.tryGetRuleHost() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("IngressWrapper.tryGetRuleHost() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} + +func TestIngressWrapper_tryGetStatusHost(t *testing.T) { + type fields struct { + ingress *v1.Ingress + } + tests := []struct { + name string + fields fields + want string + want1 bool + }{ + { + name: "IngressWithEmptyStatusHost", + fields: fields{ + ingress: testutil.CreateIngressWithHost("someIngress", ""), + }, + want: "", + want1: false, + }, + { + name: "IngressWithCorrectHostnameStatusHost", + fields: fields{ + ingress: testutil.CreateIngressWithStatusHostnameHost("someIngress", "google.com"), + }, + want: "google.com", + want1: true, + }, + { + name: "IngressWithCorrectIPStatusHost", + fields: fields{ + ingress: testutil.CreateIngressWithStatusIPHost("someIngress", "1.1.1.1"), + }, + want: "1.1.1.1", + want1: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + iw := &IngressWrapper{ + ingress: tt.fields.ingress, + } + got, got1 := iw.tryGetStatusHost() + if got != tt.want { + t.Errorf("IngressWrapper.tryGetStatusHost() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("IngressWrapper.tryGetStatusHost() got1 = %v, want %v", got1, tt.want1) } }) } diff --git a/pkg/testutil/kube.go b/pkg/testutil/kube.go index a72d1d7b..e80b1fdd 100644 --- a/pkg/testutil/kube.go +++ b/pkg/testutil/kube.go @@ -118,6 +118,28 @@ func CreateIngressWithHostAndEmptyTLSHost(name string, host string) *v1.Ingress return ingress } +func CreateIngressWithStatusHostnameHost(name string, host string) *v1.Ingress { + ingress := CreateIngress(name) + ingress.Status.LoadBalancer.Ingress = []v1.IngressLoadBalancerIngress{ + { + Hostname: host, + }, + } + + return ingress +} + +func CreateIngressWithStatusIPHost(name string, host string) *v1.Ingress { + ingress := CreateIngress(name) + ingress.Status.LoadBalancer.Ingress = []v1.IngressLoadBalancerIngress{ + { + IP: host, + }, + } + + return ingress +} + func CreateForecastleApp(name string, url string, group string, icon string) *v1alpha1.ForecastleApp { return &v1alpha1.ForecastleApp{ ObjectMeta: metav1.ObjectMeta{