Skip to content

Commit

Permalink
feat: Adds notional support for extracting the url into the hawtio.St…
Browse files Browse the repository at this point in the history
…atus #100

* While the extraction of the route url is quite straightforward, the
  use of ingress path rules and no hosts makes the return of a single
  string quite difficult. This may well need work in the future to
  improve the value returned
  • Loading branch information
phantomjinx committed Jan 16, 2024
1 parent 7e323e9 commit f1c359f
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pkg/controller/hawtio/hawtio_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,9 @@ func (r *ReconcileHawtio) Reconcile(ctx context.Context, request reconcile.Reque
// And requeue to create a new route in the next reconcile loop
return reconcile.Result{Requeue: true}, nil
}
} else {
ingressRouteURL = kresources.GetIngressURL(ingress)
hawtioCopy.Status.URL = ingressRouteURL
}

// Reconcile console link in OpenShift console
Expand Down
71 changes: 71 additions & 0 deletions pkg/resources/kubernetes/ingress.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package kubernetes

import (
"strconv"

hawtiov1 "github.com/hawtio/hawtio-operator/pkg/apis/hawtio/v1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
Expand Down Expand Up @@ -67,3 +69,72 @@ func NewIngress(hawtio *hawtiov1.Hawtio, servingSecret *corev1.Secret) *networki

return ingress
}

// GetIngressURL determines the full URL of the given ingress
func GetIngressURL(ingress *networkingv1.Ingress) string {
var scheme string
if len(ingress.Spec.TLS) > 0 {
scheme = "https"
} else {
scheme = "http"
}

host, port := getIngressHostAndPort(ingress)
path := getIngressPath(ingress)

url := scheme + "://" + host
if len(port) > 0 {
url = url + ":" + port
}

return url + path
}

func getIngressHostAndPort(ingress *networkingv1.Ingress) (string, string) {
ingressStatuses := ingress.Status.LoadBalancer.Ingress
if len(ingressStatuses) == 0 {
for _, ingressRule := range ingress.Spec.Rules {
if len(ingressRule.Host) > 0 {
return ingressRule.Host, ""
}
}

return "*", "" // host must be a wildcard
}

// get host or ip of the first ingress status available
var host string
port := ""
for _, ingressStatus := range ingress.Status.LoadBalancer.Ingress {
if len(ingressStatus.Hostname) > 0 {
host = ingressStatus.Hostname
} else if len(ingressStatus.IP) > 0 {
host = ingressStatus.IP
}

if len(host) > 0 {
for _, statusPort := range ingressStatus.Ports {
port = strconv.FormatInt(int64(statusPort.Port), 10)
continue // get the first port
}
}
}

if len(host) == 0 {
return "*", port
}

return host, port
}

func getIngressPath(ingress *networkingv1.Ingress) string {
for _, ingressRule := range ingress.Spec.Rules {
if ingressRule.IngressRuleValue.HTTP != nil {
for _, httpPath := range ingressRule.IngressRuleValue.HTTP.Paths {
return httpPath.Path
}
}
}

return "/"
}
73 changes: 73 additions & 0 deletions pkg/resources/kubernetes/ingress_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package kubernetes

import (
"testing"

corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/hawtio/hawtio-operator/pkg/resources"

"github.com/stretchr/testify/assert"
)

func TestGetIngressURL(t *testing.T) {
annotations := map[string]string{}
annotations["nginx.ingress.kubernetes.io/backend-protocol"] = "HTTPS"
annotations["nginx.ingress.kubernetes.io/force-ssl-redirect"] = "true"
annotations["nginx.ingress.kubernetes.io/rewrite-target"] = "/$1"

labels := map[string]string{
resources.LabelAppKey: "hawtio",
}
pathPrefix := networkingv1.PathTypePrefix
name := "hawtio-online"

ingress := &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Annotations: annotations,
Labels: labels,
Name: name,
},
Spec: networkingv1.IngressSpec{
TLS: []networkingv1.IngressTLS{
{
SecretName: "some-tls-secret",
},
},
Rules: []networkingv1.IngressRule{
{
IngressRuleValue: networkingv1.IngressRuleValue{
HTTP: &networkingv1.HTTPIngressRuleValue{
Paths: []networkingv1.HTTPIngressPath{{
Path: "/(.*)",
PathType: &pathPrefix,
Backend: networkingv1.IngressBackend{
Service: &networkingv1.IngressServiceBackend{
Name: name,
Port: networkingv1.ServiceBackendPort{
Number: 443,
},
},
},
}},
},
},
},
},
},
Status: networkingv1.IngressStatus{
LoadBalancer: corev1.LoadBalancerStatus{
Ingress: []corev1.LoadBalancerIngress{
{
IP: "192.168.99.9",
},
},
},
},
}

url := GetIngressURL(ingress)
assert.Equal(t, "https://192.168.99.9/(.*)", url)
}

0 comments on commit f1c359f

Please sign in to comment.