Skip to content

Commit

Permalink
feat: Add support for API served via HTTPS when preferService: true (#…
Browse files Browse the repository at this point in the history
…772)

* feat: HTTPS admin URL

Signed-off-by: Igor Beliakov <demtis.register@gmail.com>

* chore: added tests for getGrafanaAdminUrl

Signed-off-by: Igor Beliakov <demtis.register@gmail.com>

Co-authored-by: Hubert Stefanski <35736504+HubertStefanski@users.noreply.github.com>
  • Loading branch information
weisdd and HVBE committed Jun 12, 2022
1 parent 09f11cf commit 3fe7486
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 1 deletion.
15 changes: 14 additions & 1 deletion controllers/grafana/grafana_controller.go
Expand Up @@ -269,7 +269,20 @@ func (r *ReconcileGrafana) getGrafanaAdminUrl(cr *grafanav1alpha1.Grafana, state

// Otherwise rely on the service
if state.GrafanaService != nil {
return fmt.Sprintf("http://%v.%v.svc.cluster.local:%d", state.GrafanaService.Name, cr.Namespace,
protocol := "http"

if cr.Spec.Config.Server != nil {
switch cr.Spec.Config.Server.Protocol {
case "", "http":
protocol = "http"
case "https":
protocol = "https"
default:
return "", stdErr.New(fmt.Sprintf("server protocol %v is not supported, please use either http or https", protocol))
}
}

return fmt.Sprintf("%v://%v.%v.svc.cluster.local:%d", protocol, state.GrafanaService.Name, cr.Namespace,
servicePort), nil
}

Expand Down
215 changes: 215 additions & 0 deletions controllers/grafana/grafana_controller_test.go
@@ -0,0 +1,215 @@
package grafana

import (
"testing"

grafanav1alpha1 "github.com/grafana-operator/grafana-operator/v4/api/integreatly/v1alpha1"
"github.com/grafana-operator/grafana-operator/v4/controllers/common"
routev1 "github.com/openshift/api/route/v1"

"github.com/stretchr/testify/assert"
v1 "k8s.io/api/core/v1"
netv1 "k8s.io/api/networking/v1"
)

func TestReconcileGrafana_getGrafanaAdminUrl(t *testing.T) {
r := &ReconcileGrafana{}

/*
Service is NOT preferred
*/

t.Run("Route", func(t *testing.T) {
cr := &grafanav1alpha1.Grafana{}

state := &common.ClusterState{
GrafanaRoute: &routev1.Route{
Spec: routev1.RouteSpec{
Host: "route",
},
},
}
want := "https://route"

got, err := r.getGrafanaAdminUrl(cr, state)
assert.Nil(t, err)
assert.Equal(t, want, got)
})

t.Run("Ingress", func(t *testing.T) {
cr := &grafanav1alpha1.Grafana{
Spec: grafanav1alpha1.GrafanaSpec{
Ingress: &grafanav1alpha1.GrafanaIngress{
Hostname: "ingress",
},
},
}

state := &common.ClusterState{
GrafanaIngress: &netv1.Ingress{},
}

want := "https://ingress"

got, err := r.getGrafanaAdminUrl(cr, state)
assert.Nil(t, err)
assert.Equal(t, want, got)
})

t.Run("Ingress with empty spec, LB with Hostname", func(t *testing.T) {
cr := &grafanav1alpha1.Grafana{
Spec: grafanav1alpha1.GrafanaSpec{
Ingress: &grafanav1alpha1.GrafanaIngress{},
},
}

state := &common.ClusterState{
GrafanaIngress: &netv1.Ingress{
Status: netv1.IngressStatus{
LoadBalancer: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
Hostname: "lbhostname",
},
},
},
},
},
}

want := "https://lbhostname"

got, err := r.getGrafanaAdminUrl(cr, state)
assert.Nil(t, err)
assert.Equal(t, want, got)
})

t.Run("Ingress with empty spec, LB with IP", func(t *testing.T) {
cr := &grafanav1alpha1.Grafana{
Spec: grafanav1alpha1.GrafanaSpec{
Ingress: &grafanav1alpha1.GrafanaIngress{},
},
}

state := &common.ClusterState{
GrafanaIngress: &netv1.Ingress{
Status: netv1.IngressStatus{
LoadBalancer: v1.LoadBalancerStatus{
Ingress: []v1.LoadBalancerIngress{
{
IP: "1.2.3.4",
},
},
},
},
},
}

want := "https://1.2.3.4"

got, err := r.getGrafanaAdminUrl(cr, state)
assert.Nil(t, err)
assert.Equal(t, want, got)
})

t.Run("Empty specs", func(t *testing.T) {
cr := &grafanav1alpha1.Grafana{}

state := &common.ClusterState{}

_, err := r.getGrafanaAdminUrl(cr, state)
assert.NotNil(t, err)
})

/*
Service IS preferred
*/

type Srv = grafanav1alpha1.GrafanaConfigServer

testsPreferService := []struct {
name string
server *Srv
want string
wantFail bool
}{
{
name: "server spec is nil",
server: nil,
want: "http://grafana.monitoring.svc.cluster.local:3000",
wantFail: false,
},
{
name: "server protocol: not specified",
server: &Srv{Protocol: ""},
want: "http://grafana.monitoring.svc.cluster.local:3000",
wantFail: false,
},
{
name: "server protocol: http",
server: &Srv{Protocol: "http"},
want: "http://grafana.monitoring.svc.cluster.local:3000",
wantFail: false,
},
{
name: "server protocol: https",
server: &Srv{Protocol: "https"},
want: "https://grafana.monitoring.svc.cluster.local:3000",
wantFail: false,
},
{
name: "server protocol: h2",
server: &Srv{Protocol: "h2"},
want: "",
wantFail: true,
},
{
name: "server protocol: socket",
server: &Srv{Protocol: "socket"},
want: "",
wantFail: true,
},
}

for _, tt := range testsPreferService {
preferService := true

t.Run(tt.name, func(t *testing.T) {
cr := &grafanav1alpha1.Grafana{
Spec: grafanav1alpha1.GrafanaSpec{
// Ingress is set only to make sure PreferService is respected
Ingress: &grafanav1alpha1.GrafanaIngress{
Hostname: "ingress",
},
Client: &grafanav1alpha1.GrafanaClient{
PreferService: &preferService,
},
Config: grafanav1alpha1.GrafanaConfig{
Server: tt.server,
},
},
}
cr.Namespace = "monitoring"

state := &common.ClusterState{
// GrafanaRoute is set only to make sure PreferService is respected
GrafanaRoute: &routev1.Route{
Spec: routev1.RouteSpec{
Host: "route",
},
},
GrafanaService: &v1.Service{},
}
state.GrafanaService.Name = "grafana"

got, err := r.getGrafanaAdminUrl(cr, state)

if tt.wantFail {
assert.NotNil(t, err)
} else {
assert.Nil(t, err)
assert.Equal(t, tt.want, got)
}
})
}
}
6 changes: 6 additions & 0 deletions controllers/model/grafanaDeployment.go
Expand Up @@ -452,6 +452,9 @@ func getLivenessProbe(cr *v1alpha1.Grafana, delay, timeout, failure int32) *v13.
var period int32 = 10
var success int32 = 1
var scheme = v13.URISchemeHTTP
if cr.Spec.Config.Server != nil && cr.Spec.Config.Server.Protocol == "https" {
scheme = v13.URISchemeHTTPS
}

if cr.Spec.LivenessProbeSpec != nil && cr.Spec.LivenessProbeSpec.InitialDelaySeconds != nil {
delay = *cr.Spec.LivenessProbeSpec.InitialDelaySeconds
Expand Down Expand Up @@ -497,6 +500,9 @@ func getReadinessProbe(cr *v1alpha1.Grafana, delay, timeout, failure int32) *v13
var period int32 = 10
var success int32 = 1
var scheme = v13.URISchemeHTTP
if cr.Spec.Config.Server != nil && cr.Spec.Config.Server.Protocol == "https" {
scheme = v13.URISchemeHTTPS
}

if cr.Spec.ReadinessProbeSpec != nil && cr.Spec.ReadinessProbeSpec.InitialDelaySeconds != nil {
delay = *cr.Spec.ReadinessProbeSpec.InitialDelaySeconds
Expand Down

0 comments on commit 3fe7486

Please sign in to comment.