Skip to content

Commit 01cb822

Browse files
committed
Add LokiStack operator status integration
Integrate with LokiStack operator to use its status conditions instead of querying the Loki status endpoint. This adds support for detecting Loki readiness through the operator's status API when available. Changes: - Add github.com/grafana/loki/operator/apis/loki dependency - Add LokiStackStatus field to Loki config - Check operator status in getLokiStatus before querying status URL - Prevent status URL usage when using Loki operator
1 parent a2cf608 commit 01cb822

File tree

16 files changed

+5404
-16
lines changed

16 files changed

+5404
-16
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ require (
3232
github.com/gogo/protobuf v1.3.2 // indirect
3333
github.com/google/gnostic-models v0.7.0 // indirect
3434
github.com/google/uuid v1.6.0 // indirect
35+
github.com/grafana/loki/operator/apis/loki v0.0.0-20241021105923-5e970e50b166 // indirect
3536
github.com/josharian/intern v1.0.0 // indirect
3637
github.com/jpillora/backoff v1.0.0 // indirect
3738
github.com/mailru/easyjson v0.9.0 // indirect
@@ -63,6 +64,7 @@ require (
6364
k8s.io/klog/v2 v2.130.1 // indirect
6465
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
6566
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
67+
sigs.k8s.io/controller-runtime v0.20.4 // indirect
6668
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
6769
sigs.k8s.io/randfill v1.0.0 // indirect
6870
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
5353
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
5454
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
5555
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
56+
github.com/grafana/loki/operator/apis/loki v0.0.0-20241021105923-5e970e50b166 h1:cmG5fwmF+0PsyerLecb7CU4bzNRg5+tDgO3PiNxskKo=
57+
github.com/grafana/loki/operator/apis/loki v0.0.0-20241021105923-5e970e50b166/go.mod h1:QggEReYyQzjnwTlj9hMeRaI2M/w3UPAwrMOXYzIyonc=
5658
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
5759
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
5860
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
@@ -233,6 +235,8 @@ k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOP
233235
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
234236
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
235237
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
238+
sigs.k8s.io/controller-runtime v0.20.4 h1:X3c+Odnxz+iPTRobG4tp092+CvBU9UK0t/bRf+n0DGU=
239+
sigs.k8s.io/controller-runtime v0.20.4/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY=
236240
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
237241
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
238242
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=

pkg/config/loki.go

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,28 @@ import (
44
"fmt"
55
"strings"
66

7+
lokiv1 "github.com/grafana/loki/operator/apis/loki/v1"
78
"github.com/netobserv/network-observability-console-plugin/pkg/utils"
89
)
910

1011
type Loki struct {
11-
URL string `yaml:"url" json:"url"`
12-
Labels []string `yaml:"labels" json:"labels"`
13-
FieldsType map[string]string `yaml:"fieldsType" json:"fieldsType"`
14-
FieldsFormat map[string]string `yaml:"fieldsFormat" json:"fieldsFormat"`
15-
StatusURL string `yaml:"statusUrl,omitempty" json:"statusUrl,omitempty"`
16-
Timeout Duration `yaml:"timeout,omitempty" json:"timeout,omitempty"`
17-
TenantID string `yaml:"tenantID,omitempty" json:"tenantID,omitempty"`
18-
TokenPath string `yaml:"tokenPath,omitempty" json:"tokenPath,omitempty"`
19-
SkipTLS bool `yaml:"skipTls,omitempty" json:"skipTls,omitempty"`
20-
CAPath string `yaml:"caPath,omitempty" json:"caPath,omitempty"`
21-
StatusSkipTLS bool `yaml:"statusSkipTls,omitempty" json:"statusSkipTls,omitempty"`
22-
StatusCAPath string `yaml:"statusCaPath,omitempty" json:"statusCaPath,omitempty"`
23-
StatusUserCertPath string `yaml:"statusUserCertPath,omitempty" json:"statusUserCertPath,omitempty"`
24-
StatusUserKeyPath string `yaml:"statusUserKeyPath,omitempty" json:"statusUserKeyPath,omitempty"`
25-
UseMocks bool `yaml:"useMocks,omitempty" json:"useMocks,omitempty"`
26-
ForwardUserToken bool `yaml:"forwardUserToken,omitempty" json:"forwardUserToken,omitempty"`
12+
URL string `yaml:"url" json:"url"`
13+
Labels []string `yaml:"labels" json:"labels"`
14+
FieldsType map[string]string `yaml:"fieldsType" json:"fieldsType"`
15+
FieldsFormat map[string]string `yaml:"fieldsFormat" json:"fieldsFormat"`
16+
StatusURL string `yaml:"statusUrl,omitempty" json:"statusUrl,omitempty"`
17+
Timeout Duration `yaml:"timeout,omitempty" json:"timeout,omitempty"`
18+
TenantID string `yaml:"tenantID,omitempty" json:"tenantID,omitempty"`
19+
TokenPath string `yaml:"tokenPath,omitempty" json:"tokenPath,omitempty"`
20+
SkipTLS bool `yaml:"skipTls,omitempty" json:"skipTls,omitempty"`
21+
CAPath string `yaml:"caPath,omitempty" json:"caPath,omitempty"`
22+
Status *lokiv1.LokiStackStatus `yaml:"status,omitempty" json:"status,omitempty"`
23+
StatusSkipTLS bool `yaml:"statusSkipTls,omitempty" json:"statusSkipTls,omitempty"`
24+
StatusCAPath string `yaml:"statusCaPath,omitempty" json:"statusCaPath,omitempty"`
25+
StatusUserCertPath string `yaml:"statusUserCertPath,omitempty" json:"statusUserCertPath,omitempty"`
26+
StatusUserKeyPath string `yaml:"statusUserKeyPath,omitempty" json:"statusUserKeyPath,omitempty"`
27+
UseMocks bool `yaml:"useMocks,omitempty" json:"useMocks,omitempty"`
28+
ForwardUserToken bool `yaml:"forwardUserToken,omitempty" json:"forwardUserToken,omitempty"`
2729
labelsMap map[string]struct{}
2830
}
2931

pkg/handler/loki.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,18 @@ func getLokiNamesForPrefix(cfg *config.Loki, lokiClient httpclient.Caller, filts
198198
}
199199

200200
func (h *Handlers) getLokiStatus(r *http.Request) ([]byte, int, error) {
201+
// Check if the status was provided by the operator
202+
if h.Cfg.Loki.Status != nil {
203+
for _, conditions := range h.Cfg.Loki.Status.Conditions {
204+
if conditions.Reason == "ReadyComponents" {
205+
if conditions.Status == "True" {
206+
return []byte("ready"), 200, nil
207+
}
208+
break
209+
}
210+
}
211+
return []byte("pending"), 400, nil
212+
}
201213
lokiClient := newLokiClient(&h.Cfg.Loki, r.Header, true)
202214
baseURL := strings.TrimRight(h.Cfg.Loki.GetStatusURL(), "/")
203215
return executeLokiQuery(fmt.Sprintf("%s/%s", baseURL, "ready"), lokiClient)
@@ -231,6 +243,10 @@ func (h *Handlers) LokiMetrics() func(w http.ResponseWriter, r *http.Request) {
231243
writeError(w, http.StatusBadRequest, "Loki is disabled")
232244
return
233245
}
246+
if h.Cfg.Loki.Status != nil {
247+
writeError(w, http.StatusBadRequest, "Loki status URL is not usable with Loki operator")
248+
return
249+
}
234250
lokiClient := newLokiClient(&h.Cfg.Loki, r.Header, true)
235251
baseURL := strings.TrimRight(h.Cfg.Loki.GetStatusURL(), "/")
236252

@@ -250,6 +266,10 @@ func (h *Handlers) LokiBuildInfos() func(w http.ResponseWriter, r *http.Request)
250266
writeError(w, http.StatusBadRequest, "Loki is disabled")
251267
return
252268
}
269+
if h.Cfg.Loki.Status != nil {
270+
writeError(w, http.StatusBadRequest, "Loki status URL is not usable with Loki operator")
271+
return
272+
}
253273
lokiClient := newLokiClient(&h.Cfg.Loki, r.Header, true)
254274
baseURL := strings.TrimRight(h.Cfg.Loki.GetStatusURL(), "/")
255275

@@ -264,6 +284,10 @@ func (h *Handlers) LokiBuildInfos() func(w http.ResponseWriter, r *http.Request)
264284
}
265285

266286
func (h *Handlers) fetchLokiConfig(cl httpclient.Caller, output any) error {
287+
if h.Cfg.Loki.Status != nil {
288+
return fmt.Errorf("loki status url is not usable with Loki operator")
289+
}
290+
267291
baseURL := strings.TrimRight(h.Cfg.Loki.GetStatusURL(), "/")
268292

269293
resp, _, err := executeLokiQuery(fmt.Sprintf("%s/%s", baseURL, "config"), cl)

0 commit comments

Comments
 (0)