Skip to content

Commit

Permalink
feat(ingress): fallback to status host if defined
Browse files Browse the repository at this point in the history
Signed-off-by: GitHub <[email protected]>
  • Loading branch information
aslafy-z authored Nov 9, 2024
1 parent 648ceea commit 85b12b9
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 28 deletions.
60 changes: 40 additions & 20 deletions pkg/kube/wrappers/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""
Expand Down
88 changes: 80 additions & 8 deletions pkg/kube/wrappers/ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
},
{
Expand Down Expand Up @@ -335,37 +349,95 @@ func TestIngressWrapper_supportsTLS(t *testing.T) {
}
}

func TestIngressWrapper_getHost(t *testing.T) {
func TestIngressWrapper_tryGetRuleHost(t *testing.T) {
type fields struct {
ingress *v1.Ingress
}
tests := []struct {
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 {
t.Run(tt.name, func(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)
}
})
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/testutil/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down

0 comments on commit 85b12b9

Please sign in to comment.